Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ dependencies {
shadow(runtimeOnly('net.fabricmc:tiny-remapper:0.11.0')) {
transitive = false
}
shadow(runtimeOnly('net.fabricmc:access-widener:2.1.0')) {
transitive = false
}

shadow(runtimeOnly('com.google.code.gson:gson:2.2.4')) {
transitive = false
Expand Down Expand Up @@ -96,6 +99,7 @@ shadowJar {

relocate 'net.fabricmc.mappingio', 'fr.catcore.modremapperapi.impl.lib.mappingio'
relocate 'net.fabricmc.tinyremapper', 'fr.catcore.modremapperapi.impl.lib.tinyremapper'
relocate 'net.fabricmc.accesswidener', 'fr.catcore.modremapperapi.impl.lib.accesswidener'
relocate 'com.google.gson', 'fr.catcore.modremapperapi.impl.lib.gson'
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
package io.github.fabriccompatibiltylayers.modremappingapi.impl;

import org.jetbrains.annotations.Nullable;

import java.nio.file.Path;

public abstract class ModCandidate {
public class ModCandidate {
public final String modName;
public final String modId;
public final @Nullable String accessWidenerName;

public final Path file;
public final Path original;

protected ModCandidate(String modName, String modId, Path file, Path original) {
public byte[] accessWidener;

public ModCandidate(String modName, @Nullable String accessWidenerName, Path file, Path original) {
this.modName = modName;
this.modId = modId;
this.accessWidenerName = accessWidenerName;
this.file = file;
this.original = original;
}

public ModCandidate(String modName, Path file, Path original) {
this(modName, null, file, original);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.github.fabriccompatibiltylayers.modremappingapi.impl.context;

import io.github.fabriccompatibiltylayers.modremappingapi.impl.LibraryHandler;
import io.github.fabriccompatibiltylayers.modremappingapi.impl.ModCandidate;
import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry;
import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.RemappingFlags;
import net.fabricmc.tinyremapper.TinyRemapper;
Expand All @@ -12,7 +13,7 @@

public interface ModRemapperContext {
void init();
void remapMods(Map<Path, Path> pathMap);
void remapMods(Map<ModCandidate, Path> pathMap);
void afterRemap();
void discoverMods(boolean remapClassEdits);
void gatherRemappers();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,12 @@ public void init() {
this.mappingsRegistry.generateAdditionalMappings();
}

public void remapMods(Map<Path, Path> pathMap) {
public void remapMods(Map<ModCandidate, Path> pathMap) {
Constants.MAIN_LOGGER.debug("Starting jar remapping!");
SoftLockFixer.preloadClasses();
TinyRemapper remapper = ModTrRemapper.makeRemapper(this);
Constants.MAIN_LOGGER.debug("Remapper created!");
ModTrRemapper.remapMods(remapper, pathMap, this.mappingsRegistry);
ModTrRemapper.remapMods(remapper, pathMap, this);
Constants.MAIN_LOGGER.debug("Jar remapping done!");

this.mappingsRegistry.writeFullMappings();
Expand All @@ -94,10 +94,10 @@ public void afterRemap() {

@Override
public void discoverMods(boolean remapClassEdits) {
Map<Path, Path> modPaths = this.modDiscoverer.init(remappers, remapClassEdits, this);
Map<ModCandidate, Path> modPaths = this.modDiscoverer.init(remappers, remapClassEdits, this);

for (Path path : modPaths.keySet()) {
mappingsRegistry.addModMappings(path);
for (ModCandidate candidate : modPaths.keySet()) {
mappingsRegistry.addModMappings(candidate.original);
}

mappingsRegistry.generateModMappings();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import fr.catcore.modremapperapi.utils.Constants;
import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ModRemapper;
import io.github.fabriccompatibiltylayers.modremappingapi.impl.DefaultModCandidate;
import io.github.fabriccompatibiltylayers.modremappingapi.impl.ModCandidate;
import io.github.fabriccompatibiltylayers.modremappingapi.impl.compatibility.V0ModRemapper;
import io.github.fabriccompatibiltylayers.modremappingapi.impl.discover.BaseModDiscoverer;
Expand All @@ -24,7 +23,7 @@
public class V1ModDiscoverer extends BaseModDiscoverer {
private final Map<String, List<String>> excluded = new HashMap<>();

public Map<Path, Path> init(List<ModRemapper> modRemappers, boolean remapClassEdits, ModRemapperV1Context context) {
public Map<ModCandidate, Path> init(List<ModRemapper> modRemappers, boolean remapClassEdits, ModRemapperV1Context context) {
Set<String> modFolders = new HashSet<>();

for (ModRemapper remapper : modRemappers) {
Expand Down Expand Up @@ -66,11 +65,9 @@ public Map<Path, Path> init(List<ModRemapper> modRemappers, boolean remapClassEd
throw new RuntimeException(e);
}

Map<Path, Path> modPaths = mods.stream()
Map<ModCandidate, Path> modPaths = mods.stream()
.filter(entry -> Files.exists(entry.original))
.collect(Collectors.groupingBy(entry -> entry.modId))
.entrySet().stream()
.collect(Collectors.toMap(entry -> entry.getValue().get(0).original, entry -> entry.getValue().get(0).file));
.collect(Collectors.toMap(entry -> entry, entry -> entry.file));

if (!remapClassEdits) {
modPaths = excludeClassEdits(modPaths, mainTempDir, context.getMappingsRegistry());
Expand All @@ -81,15 +78,15 @@ public Map<Path, Path> init(List<ModRemapper> modRemappers, boolean remapClassEd

private void handleV0Excluded(List<ModCandidate> mods) throws IOException, URISyntaxException {
for (ModCandidate modCandidate : mods) {
if (excluded.containsKey(modCandidate.modId)) {
if (excluded.containsKey(modCandidate.modName)) {
if (Files.isDirectory(modCandidate.file)) {
for (String excluded : excluded.get(modCandidate.modId)) {
for (String excluded : excluded.get(modCandidate.modName)) {
if (Files.deleteIfExists(modCandidate.file.resolve(excluded))) {
Constants.MAIN_LOGGER.debug("File deleted: " + modCandidate.file.resolve(excluded));
}
}
} else {
FileUtils.removeEntriesFromZip(modCandidate.file, excluded.get(modCandidate.modId));
FileUtils.removeEntriesFromZip(modCandidate.file, excluded.get(modCandidate.modName));
}
}
}
Expand Down Expand Up @@ -136,7 +133,7 @@ public Optional<ModCandidate> discoverFolderMod(Path folder, Path destinationFol

if (hasClasses[0]) {
return Optional.of(
new DefaultModCandidate(
new ModCandidate(
name,
destination,
folder
Expand Down Expand Up @@ -166,7 +163,7 @@ public Optional<ModCandidate> discoverFileMod(Path file, Path destinationFolder)

if (found) {
return Optional.of(
new DefaultModCandidate(
new ModCandidate(
modName,
destinationFolder.resolve(fileName),
file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ public List<ModCandidate> discoverMods(Path folder, Path destination) throws IOE
return mods;
}

public Map<Path, Path> excludeClassEdits(Map<Path, Path> modPaths, Path tempFolder, MappingsRegistry mappingsRegistry) {
Map<Path, Path> map = new HashMap<>();
Map<Path, Path> convertMap = new HashMap<>();
public Map<ModCandidate, Path> excludeClassEdits(Map<ModCandidate, Path> modPaths, Path tempFolder, MappingsRegistry mappingsRegistry) {
Map<ModCandidate, Path> map = new HashMap<>();
Map<ModCandidate, Path> convertMap = new HashMap<>();

for (Map.Entry<Path, Path> entry : modPaths.entrySet()) {
for (Map.Entry<ModCandidate, Path> entry : modPaths.entrySet()) {
ModCandidate modCandidate = entry.getKey();
Path tempDir = tempFolder.resolve(entry.getValue().getParent().getFileName().toString());

if (!Files.exists(tempDir)) {
Expand All @@ -64,24 +65,30 @@ public Map<Path, Path> excludeClassEdits(Map<Path, Path> modPaths, Path tempFold
}

Path tempFile = tempDir.resolve(entry.getValue().getFileName().toString());
map.put(tempFile, entry.getValue());
map.put(new ModCandidate(
modCandidate.modName,
modCandidate.accessWidenerName,
modCandidate.file,
tempFile
), entry.getValue());
convertMap.put(entry.getKey(), tempFile);
}

List<Path> errored = new ArrayList<>();
List<ModCandidate> errored = new ArrayList<>();

for (Map.Entry<Path, Path> entry : convertMap.entrySet()) {
for (Map.Entry<ModCandidate, Path> entry : convertMap.entrySet()) {
ModCandidate modCandidate = entry.getKey();
try {
if (Files.isDirectory(entry.getKey())) {
FileUtils.zipFolder(entry.getKey(), entry.getValue());
if (Files.isDirectory(modCandidate.original)) {
FileUtils.zipFolder(modCandidate.original, entry.getValue());
} else {
Files.copy(entry.getKey(), entry.getValue(), StandardCopyOption.REPLACE_EXISTING);
Files.copy(modCandidate.original, entry.getValue(), StandardCopyOption.REPLACE_EXISTING);
}

FileUtils.removeEntriesFromZip(entry.getValue(), mappingsRegistry.getVanillaClassNames());
} catch (IOException | URISyntaxException e) {
e.printStackTrace();
errored.add(entry.getValue());
errored.add(modCandidate);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper;

import io.github.fabriccompatibiltylayers.modremappingapi.impl.ModCandidate;
import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.ModRemapperContext;
import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingTreeHelper;
import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry;
import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.minecraft.MinecraftRemapper;
import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.resource.RefmapRemapper;
import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor.MixinPostApplyVisitor;
import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils;
import net.fabricmc.accesswidener.AccessWidenerReader;
import net.fabricmc.accesswidener.AccessWidenerRemapper;
import net.fabricmc.accesswidener.AccessWidenerWriter;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.mappingio.tree.MappingTree;
import net.fabricmc.tinyremapper.NonClassCopyMode;
import net.fabricmc.tinyremapper.OutputConsumerPath;
import net.fabricmc.tinyremapper.TinyRemapper;
import net.fabricmc.tinyremapper.extension.mixin.MixinExtension;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import org.objectweb.asm.commons.Remapper;

import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;

@ApiStatus.Internal
public class ModTrRemapper {
Expand Down Expand Up @@ -61,12 +72,69 @@ public static TinyRemapper makeRemapper(ModRemapperContext context) {
return remapper;
}

public static void remapMods(TinyRemapper remapper, Map<Path, Path> paths, MappingsRegistry mappingsRegistry) {
public static void remapMods(TinyRemapper remapper, Map<ModCandidate, Path> paths, ModRemapperContext context) {
List<OutputConsumerPath> outputConsumerPaths = new ArrayList<>();

List<OutputConsumerPath.ResourceRemapper> resourceRemappers = new ArrayList<>(NonClassCopyMode.FIX_META_INF.remappers);
resourceRemappers.add(new RefmapRemapper());

TrRemapperHelper.applyRemapper(remapper, paths, outputConsumerPaths, resourceRemappers, true, mappingsRegistry.getSourceNamespace(), mappingsRegistry.getTargetNamespace());
Consumer<TinyRemapper> consumer = getRemapperConsumer(paths, context);

TrRemapperHelper.applyRemapper(
remapper,
paths.entrySet().stream().collect(Collectors.toMap(entry -> entry.getKey().original, Map.Entry::getValue)),
outputConsumerPaths,
resourceRemappers,
true,
context.getMappingsRegistry().getSourceNamespace(),
context.getMappingsRegistry().getTargetNamespace(),
consumer
);

if (context.getRemappingFlags().contains(RemappingFlags.ACCESS_WIDENER)) {
for (Map.Entry<ModCandidate, Path> entry : paths.entrySet()) {
ModCandidate candidate = entry.getKey();
Path jarPath = entry.getValue();

if (candidate.accessWidenerName != null && candidate.accessWidener != null) {
try (FileSystem fs = FileUtils.getJarFileSystem(jarPath)) {
Files.delete(fs.getPath(candidate.accessWidenerName));
Files.write(fs.getPath(candidate.accessWidenerName), candidate.accessWidener);
} catch (Throwable t) {
throw new RuntimeException("Error while writing remapped access widener for '" + candidate.modName + "'", t);
}
}
}
}
}

private static @Nullable Consumer<TinyRemapper> getRemapperConsumer(Map<ModCandidate, Path> paths, ModRemapperContext context) {
Consumer<TinyRemapper> consumer = null;

if (context.getRemappingFlags().contains(RemappingFlags.ACCESS_WIDENER)) {
consumer = (currentRemapper) -> {
for (Map.Entry<ModCandidate, Path> entry : paths.entrySet()) {
ModCandidate candidate = entry.getKey();

if (candidate.accessWidenerName != null) {
try (FileSystem jarFs = FileUtils.getJarFileSystem(candidate.original)) {
candidate.accessWidener = remapAccessWidener(Files.readAllBytes(jarFs.getPath(candidate.accessWidenerName)), currentRemapper.getRemapper(), context.getMappingsRegistry().getTargetNamespace());
} catch (Throwable t) {
throw new RuntimeException("Error while remapping access widener for '" + candidate.modName + "'", t);
}
}
}
};
}

return consumer;
}

private static byte[] remapAccessWidener(byte[] data, Remapper remapper, String targetNamespace) {
AccessWidenerWriter writer = new AccessWidenerWriter();
AccessWidenerRemapper remappingDecorator = new AccessWidenerRemapper(writer, remapper, "intermediary", targetNamespace);
AccessWidenerReader accessWidenerReader = new AccessWidenerReader(remappingDecorator);
accessWidenerReader.read(data, "intermediary");
return writer.write();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@

@ApiStatus.Internal
public enum RemappingFlags {
MIXIN
MIXIN,
ACCESS_WIDENER
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,22 @@
import net.fabricmc.tinyremapper.OutputConsumerPath;
import net.fabricmc.tinyremapper.TinyRemapper;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

@ApiStatus.Internal
public class TrRemapperHelper {
public static void applyRemapper(TinyRemapper remapper, Map<Path, Path> paths, List<OutputConsumerPath> outputConsumerPaths, List<OutputConsumerPath.ResourceRemapper> resourceRemappers, boolean analyzeMapping, String srcNamespace, String targetNamespace) {
applyRemapper(remapper, paths, outputConsumerPaths, resourceRemappers, analyzeMapping, srcNamespace, targetNamespace, null);
}

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) {
try {
Map<Path, InputTag> tagMap = new HashMap<>();

Expand Down Expand Up @@ -43,6 +49,8 @@ public static void applyRemapper(TinyRemapper remapper, Map<Path, Path> paths, L
}

if (analyzeMapping) ModRemappingAPIImpl.getCurrentContext().getMappingsRegistry().completeMappingsFromTr(remapper.getEnvironment(), srcNamespace);

if (action != null) action.accept(remapper);
} catch (Exception e) {
remapper.finish();
outputConsumerPaths.forEach(o -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,14 @@ private static void zipFile(File fileToZip, String fileName, ZipOutputStream zip
ZIP_PROPERTIES.put("encoding", "UTF-8");
}

@ApiStatus.Internal
public static FileSystem getJarFileSystem(Path path) throws URISyntaxException, IOException {
return FileSystems.newFileSystem(new URI("jar:" + path.toUri()), ZIP_PROPERTIES);
}

@ApiStatus.Internal
public static void removeEntriesFromZip(Path zipPath, List<String> entries) throws IOException, URISyntaxException {
try (FileSystem zipfs = FileSystems.newFileSystem(new URI("jar:" + zipPath.toUri()), ZIP_PROPERTIES)) {
try (FileSystem zipfs = getJarFileSystem(zipPath)) {
for (String entryName : entries) {
Path entryPath = zipfs.getPath(entryName);

Expand Down
Loading