From f963f6d330f9add4d2e87b4bb860e68b6480ffa2 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Mon, 31 Mar 2025 23:44:50 +0200 Subject: [PATCH 01/14] Start working on V2 api --- .../modremappingapi/Dummy.java | 4 + .../modremappingapi/api/v2/ModDiscoverer.java | 25 ++++++ .../modremappingapi/api/v2/ModRemapper.java | 9 ++ .../impl/ModDiscovererImpl.java | 76 +++++++++++++++++ .../impl/ModRemappingAPIImpl.java | 26 ++++++ .../impl/context/BaseModRemapperContext.java | 2 +- .../impl/context/ModRemapperContext.java | 4 +- .../impl/context/v1/ModRemapperV1Context.java | 7 +- .../impl/context/v2/ModRemmaperV2Context.java | 83 +++++++++++++++++++ 9 files changed, 231 insertions(+), 5 deletions(-) create mode 100644 src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/Dummy.java create mode 100644 src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModDiscoverer.java create mode 100644 src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java create mode 100644 src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/ModDiscovererImpl.java create mode 100644 src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/Dummy.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/Dummy.java new file mode 100644 index 0000000..846488d --- /dev/null +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/Dummy.java @@ -0,0 +1,4 @@ +package io.github.fabriccompatibilitylayers.modremappingapi; + +public class Dummy { +} diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModDiscoverer.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModDiscoverer.java new file mode 100644 index 0000000..880f3d5 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModDiscoverer.java @@ -0,0 +1,25 @@ +package io.github.fabriccompatibilitylayers.modremappingapi.api.v2; + +import io.github.fabriccompatibilitylayers.modremappingapi.impl.ModDiscovererImpl; + +import java.util.function.Predicate; +import java.util.regex.Pattern; + +public interface ModDiscoverer { + static Builder builder(String folderName) { + return new ModDiscovererImpl.BuilderImpl(folderName); + } + + String getFolderName(); + Pattern getFileNameMatcher(); + boolean searchRecursively(); + Predicate getDirectoryFilter(); + + interface Builder { + Builder fileNameMatcher(String pattern); + Builder searchRecursively(boolean searchRecursively); + Builder directoryFilter(Predicate filter); + + ModDiscoverer build(); + } +} diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java new file mode 100644 index 0000000..21f8952 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java @@ -0,0 +1,9 @@ +package io.github.fabriccompatibilitylayers.modremappingapi.api.v2; + +import java.util.List; + +public interface ModRemapper { + String getContextId(); + + List getModDiscoverers(); +} diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/ModDiscovererImpl.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/ModDiscovererImpl.java new file mode 100644 index 0000000..05ac89a --- /dev/null +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/ModDiscovererImpl.java @@ -0,0 +1,76 @@ +package io.github.fabriccompatibilitylayers.modremappingapi.impl; + +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModDiscoverer; +import org.jetbrains.annotations.ApiStatus; + +import java.util.function.Predicate; +import java.util.regex.Pattern; + +@ApiStatus.Internal +public class ModDiscovererImpl implements ModDiscoverer { + private final String folderName; + private final Pattern fileNameMatcher; + private final boolean searchRecursively; + private final Predicate directoryFilter; + + private ModDiscovererImpl(String folderName, Pattern fileNameMatcher, boolean searchRecursively, Predicate directoryFilter) { + this.folderName = folderName; + this.fileNameMatcher = fileNameMatcher; + this.searchRecursively = searchRecursively; + this.directoryFilter = directoryFilter; + } + + @Override + public String getFolderName() { + return folderName; + } + + @Override + public Pattern getFileNameMatcher() { + return fileNameMatcher; + } + + @Override + public boolean searchRecursively() { + return searchRecursively; + } + + @Override + public Predicate getDirectoryFilter() { + return directoryFilter; + } + + public static class BuilderImpl implements ModDiscoverer.Builder { + private final String folderName; + private String fileNameMatcher = "(.+).jar$"; + private boolean searchRecursively = false; + private Predicate directoryFilter = s -> true; + + public BuilderImpl(String folderName) { + this.folderName = folderName; + } + + @Override + public Builder fileNameMatcher(String pattern) { + this.fileNameMatcher = pattern; + return this; + } + + @Override + public Builder searchRecursively(boolean searchRecursively) { + this.searchRecursively = searchRecursively; + return this; + } + + @Override + public Builder directoryFilter(Predicate filter) { + this.directoryFilter = filter; + return this; + } + + @Override + public ModDiscoverer build() { + return new ModDiscovererImpl(folderName, Pattern.compile(fileNameMatcher), searchRecursively, directoryFilter); + } + } +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModRemappingAPIImpl.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModRemappingAPIImpl.java index d04c1ae..7f14a01 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModRemappingAPIImpl.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModRemappingAPIImpl.java @@ -2,11 +2,17 @@ import fr.catcore.wfvaio.FabricVariants; import fr.catcore.wfvaio.WhichFabricVariantAmIOn; +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModRemapper; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.ModRemapperContext; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.v1.ModRemapperV1Context; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.v2.ModRemmaperV2Context; import net.fabricmc.loader.api.FabricLoader; import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; public class ModRemappingAPIImpl { private static ModRemapperContext CURRENT_CONTEXT = null; @@ -16,6 +22,7 @@ public class ModRemappingAPIImpl { private static boolean init = false; private static boolean initializing = false; + private static final String v2EntrypointName = "mod-remapper-api:modremapper_v2"; public static void init() { if (!init && !initializing) { @@ -32,6 +39,25 @@ public static void init() { CURRENT_CONTEXT.afterRemap(); + Map> v2Remappers = FabricLoader.getInstance() + .getEntrypoints(v2EntrypointName, ModRemapper.class) + .stream().collect(Collectors.groupingBy(ModRemapper::getContextId)); + + List v2Keys = new ArrayList<>(v2Remappers.keySet()); + + for (String contextKey : v2Keys) { + ModRemmaperV2Context context = new ModRemmaperV2Context(contextKey, v2Remappers.get(contextKey)); + CURRENT_CONTEXT = context; + + Map> newRemappers = context.discoverMods(remapClassEdits) + .stream().collect(Collectors.groupingBy(ModRemapper::getContextId)); + + v2Keys.addAll(newRemappers.keySet()); + v2Remappers.putAll(newRemappers); + + context.afterRemap(); + } + initializing = false; init = true; } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/BaseModRemapperContext.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/BaseModRemapperContext.java index 2dc94b4..c516880 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/BaseModRemapperContext.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/BaseModRemapperContext.java @@ -3,7 +3,7 @@ import java.util.HashMap; import java.util.Map; -public abstract class BaseModRemapperContext implements ModRemapperContext { +public abstract class BaseModRemapperContext implements ModRemapperContext { private static final Map REGISTRY = new HashMap<>(); public BaseModRemapperContext(String id) { diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/ModRemapperContext.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/ModRemapperContext.java index 3b3532e..3ac7f14 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/ModRemapperContext.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/ModRemapperContext.java @@ -11,11 +11,11 @@ import java.util.Map; import java.util.Set; -public interface ModRemapperContext { +public interface ModRemapperContext { void init(); void remapMods(Map pathMap); void afterRemap(); - void discoverMods(boolean remapClassEdits); + List discoverMods(boolean remapClassEdits); void gatherRemappers(); Map> getMixin2TargetMap(); MappingsRegistry getMappingsRegistry(); diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java index b965a39..fd5356b 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java @@ -7,6 +7,7 @@ import io.github.fabriccompatibiltylayers.modremappingapi.impl.compatibility.V0ModRemapper; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.BaseModRemapperContext; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.MappingsRegistryInstance; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.ModRemapperContext; import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.ModTrRemapper; import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.RemappingFlags; @@ -22,7 +23,7 @@ import java.util.*; import java.util.function.Supplier; -public class ModRemapperV1Context extends BaseModRemapperContext { +public class ModRemapperV1Context extends BaseModRemapperContext { private final Set remapFlags = new HashSet<>(); private final List remappers = new ArrayList<>(); private final Map> mixin2TargetMap = new HashMap<>(); @@ -93,7 +94,7 @@ public void afterRemap() { } @Override - public void discoverMods(boolean remapClassEdits) { + public List discoverMods(boolean remapClassEdits) { Map modPaths = this.modDiscoverer.init(remappers, remapClassEdits, this); for (ModCandidate candidate : modPaths.keySet()) { @@ -105,6 +106,8 @@ public void discoverMods(boolean remapClassEdits) { this.remapMods(modPaths); modPaths.values().forEach(FabricLauncherBase.getLauncher()::addToClassPath); + + return new ArrayList<>(); } private static final String v0EntrypointName = "mod-remapper-api:modremapper"; diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java new file mode 100644 index 0000000..5343349 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java @@ -0,0 +1,83 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.impl.context.v2; + +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModRemapper; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.LibraryHandler; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.ModCandidate; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.BaseModRemapperContext; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.MappingsRegistryInstance; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.ModRemapperContext; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.RemappingFlags; +import net.fabricmc.tinyremapper.TinyRemapper; + +import java.nio.file.Path; +import java.util.*; + +public class ModRemmaperV2Context extends BaseModRemapperContext { + private final List remappers; + private final Set remapFlags = new HashSet<>(); + private final Map> mixin2TargetMap = new HashMap<>(); + private final MappingsRegistryInstance mappingsRegistry = new MappingsRegistryInstance(); + private final LibraryHandler libraryHandler = new LibraryHandler(); + + public ModRemmaperV2Context(String id, List remappers) { + super(id); + this.remappers = remappers; + } + + @Override + public void init() { + + } + + @Override + public void remapMods(Map pathMap) { + + } + + @Override + public void afterRemap() { + + } + + @Override + public List discoverMods(boolean remapClassEdits) { + for (ModRemapper remapper : remappers) { + + } + } + + @Override + public void gatherRemappers() { + + } + + @Override + public Map> getMixin2TargetMap() { + return mixin2TargetMap; + } + + @Override + public MappingsRegistry getMappingsRegistry() { + return mappingsRegistry; + } + + @Override + public void addToRemapperBuilder(TinyRemapper.Builder builder) { + + } + + @Override + public Set getRemappingFlags() { + return remapFlags; + } + + @Override + public LibraryHandler getLibraryHandler() { + return libraryHandler; + } + + public List getRemappers() { + return remappers; + } +} From c3c0b3a1013e42b5e80d8e707dc19f8c6998641c Mon Sep 17 00:00:00 2001 From: Cat Core Date: Tue, 1 Apr 2025 23:45:54 +0200 Subject: [PATCH 02/14] Some work on the mod discovery api --- build.gradle | 2 +- gradle.properties | 2 +- .../modremappingapi/api/v2/ModCandidate.java | 13 +++ ...scoverer.java => ModDiscovererConfig.java} | 13 ++- .../modremappingapi/api/v2/ModRemapper.java | 3 +- .../impl/DefaultModCandidate.java | 41 +++++++ .../impl/ModDiscovererConfigImpl.java | 109 ++++++++++++++++++ .../impl/ModDiscovererImpl.java | 76 ------------ .../impl/ModRemappingAPIImpl.java | 2 +- .../impl/context/v2/ModRemmaperV2Context.java | 13 +++ .../impl/context/v2/V2ModDiscoverer.java | 66 +++++++++++ 11 files changed, 256 insertions(+), 84 deletions(-) create mode 100644 src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModCandidate.java rename src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/{ModDiscoverer.java => ModDiscovererConfig.java} (58%) create mode 100644 src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultModCandidate.java create mode 100644 src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/ModDiscovererConfigImpl.java delete mode 100644 src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/ModDiscovererImpl.java create mode 100644 src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2ModDiscoverer.java diff --git a/build.gradle b/build.gradle index 261ca55..3bdaab2 100644 --- a/build.gradle +++ b/build.gradle @@ -58,7 +58,7 @@ dependencies { implementation(include("io.github.llamalad7:mixinextras-fabric:${project.mixin_extras_version}")) implementation(include("com.github.thecatcore.CursedMixinExtensions:fabric:1.0.0")) - implementation(include("com.github.thecatcore:WFVAIO:1.1.0")) + implementation(include("com.github.thecatcore:WFVAIO:1.2.0")) testImplementation "net.fabricmc:fabric-loader-junit:${project.loader_version}" } diff --git a/gradle.properties b/gradle.properties index a6d695d..d2005f4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties minecraft_version = 1.6.4 yarn_build = 458 - loader_version = 0.15.10 + loader_version = 0.16.11 fabric_version = 1.9.1+1.12.2 mixin_extras_version=0.2.1 spasm_version=0.2 diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModCandidate.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModCandidate.java new file mode 100644 index 0000000..1c9c3c8 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModCandidate.java @@ -0,0 +1,13 @@ +package io.github.fabriccompatibilitylayers.modremappingapi.api.v2; + +import org.jetbrains.annotations.Nullable; + +import java.nio.file.Path; + +public interface ModCandidate { + String getId(); + Path getPath(); + String getType(); + @Nullable String getAccessWidenerPath(); + @Nullable ModCandidate getParent(); +} diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModDiscoverer.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModDiscovererConfig.java similarity index 58% rename from src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModDiscoverer.java rename to src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModDiscovererConfig.java index 880f3d5..5020e0b 100644 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModDiscoverer.java +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModDiscovererConfig.java @@ -1,25 +1,30 @@ package io.github.fabriccompatibilitylayers.modremappingapi.api.v2; -import io.github.fabriccompatibilitylayers.modremappingapi.impl.ModDiscovererImpl; +import io.github.fabriccompatibilitylayers.modremappingapi.impl.ModDiscovererConfigImpl; +import java.nio.file.Path; +import java.util.List; +import java.util.function.BiFunction; import java.util.function.Predicate; import java.util.regex.Pattern; -public interface ModDiscoverer { +public interface ModDiscovererConfig { static Builder builder(String folderName) { - return new ModDiscovererImpl.BuilderImpl(folderName); + return new ModDiscovererConfigImpl.BuilderImpl(folderName); } String getFolderName(); Pattern getFileNameMatcher(); boolean searchRecursively(); Predicate getDirectoryFilter(); + BiFunction, List> getCandidateCollector(); interface Builder { Builder fileNameMatcher(String pattern); Builder searchRecursively(boolean searchRecursively); Builder directoryFilter(Predicate filter); + Builder candidateCollector(BiFunction, List> collector); - ModDiscoverer build(); + ModDiscovererConfig build(); } } diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java index 21f8952..34e8de1 100644 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java @@ -5,5 +5,6 @@ public interface ModRemapper { String getContextId(); - List getModDiscoverers(); + List getModDiscoverers(); + List collectSubRemappers(List discoveredMods); } diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultModCandidate.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultModCandidate.java new file mode 100644 index 0000000..f3ebdea --- /dev/null +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultModCandidate.java @@ -0,0 +1,41 @@ +package io.github.fabriccompatibilitylayers.modremappingapi.impl; + +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModCandidate; +import org.jetbrains.annotations.Nullable; + +import java.nio.file.Path; + +public class DefaultModCandidate implements ModCandidate { + private final String id; + private final Path path; + + public DefaultModCandidate(Path path) { + this.id = path.getFileName().toString().replace(".jar", "").replace(".zip", "").replace(" ", "_"); + this.path = path; + } + + @Override + public String getId() { + return id; + } + + @Override + public Path getPath() { + return path; + } + + @Override + public String getType() { + return "default"; + } + + @Override + public @Nullable String getAccessWidenerPath() { + return null; + } + + @Override + public @Nullable ModCandidate getParent() { + return null; + } +} diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/ModDiscovererConfigImpl.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/ModDiscovererConfigImpl.java new file mode 100644 index 0000000..ceaca59 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/ModDiscovererConfigImpl.java @@ -0,0 +1,109 @@ +package io.github.fabriccompatibilitylayers.modremappingapi.impl; + +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModCandidate; +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModDiscovererConfig; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Predicate; +import java.util.regex.Pattern; + +@ApiStatus.Internal +public class ModDiscovererConfigImpl implements ModDiscovererConfig { + private final String folderName; + private final Pattern fileNameMatcher; + private final boolean searchRecursively; + private final Predicate directoryFilter; + private final @Nullable BiFunction, List> candidateCollector; + + private ModDiscovererConfigImpl(String folderName, Pattern fileNameMatcher, boolean searchRecursively, Predicate directoryFilter, @Nullable BiFunction, List> candidateCollector) { + this.folderName = folderName; + this.fileNameMatcher = fileNameMatcher; + this.searchRecursively = searchRecursively; + this.directoryFilter = directoryFilter; + this.candidateCollector = candidateCollector; + } + + @Override + public String getFolderName() { + return folderName; + } + + @Override + public Pattern getFileNameMatcher() { + return fileNameMatcher; + } + + @Override + public boolean searchRecursively() { + return searchRecursively; + } + + @Override + public Predicate getDirectoryFilter() { + return directoryFilter; + } + + @Override + public BiFunction, List> getCandidateCollector() { + return this.candidateCollector == null ? this::defaultCandidateCollector : this.candidateCollector; + } + + private List defaultCandidateCollector(Path modPath, List fileList) { + List candidates = new ArrayList<>(); + + for (String file : fileList) { + if (file.endsWith(".class")) { + candidates.add(new DefaultModCandidate(modPath)); + break; + } + } + + return candidates; + } + + public static class BuilderImpl implements ModDiscovererConfig.Builder { + private final String folderName; + private String fileNameMatcher = "(.+).jar$"; + private boolean searchRecursively = false; + private Predicate directoryFilter = s -> true; + private BiFunction, List> candidateCollector; + + public BuilderImpl(String folderName) { + this.folderName = folderName; + } + + @Override + public Builder fileNameMatcher(String pattern) { + this.fileNameMatcher = pattern; + return this; + } + + @Override + public Builder searchRecursively(boolean searchRecursively) { + this.searchRecursively = searchRecursively; + return this; + } + + @Override + public Builder directoryFilter(Predicate filter) { + this.directoryFilter = filter; + return this; + } + + @Override + public Builder candidateCollector(BiFunction, List> collector) { + this.candidateCollector = collector; + return this; + } + + @Override + public ModDiscovererConfig build() { + return new ModDiscovererConfigImpl(folderName, Pattern.compile(fileNameMatcher), searchRecursively, directoryFilter, candidateCollector); + } + } +} diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/ModDiscovererImpl.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/ModDiscovererImpl.java deleted file mode 100644 index 05ac89a..0000000 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/ModDiscovererImpl.java +++ /dev/null @@ -1,76 +0,0 @@ -package io.github.fabriccompatibilitylayers.modremappingapi.impl; - -import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModDiscoverer; -import org.jetbrains.annotations.ApiStatus; - -import java.util.function.Predicate; -import java.util.regex.Pattern; - -@ApiStatus.Internal -public class ModDiscovererImpl implements ModDiscoverer { - private final String folderName; - private final Pattern fileNameMatcher; - private final boolean searchRecursively; - private final Predicate directoryFilter; - - private ModDiscovererImpl(String folderName, Pattern fileNameMatcher, boolean searchRecursively, Predicate directoryFilter) { - this.folderName = folderName; - this.fileNameMatcher = fileNameMatcher; - this.searchRecursively = searchRecursively; - this.directoryFilter = directoryFilter; - } - - @Override - public String getFolderName() { - return folderName; - } - - @Override - public Pattern getFileNameMatcher() { - return fileNameMatcher; - } - - @Override - public boolean searchRecursively() { - return searchRecursively; - } - - @Override - public Predicate getDirectoryFilter() { - return directoryFilter; - } - - public static class BuilderImpl implements ModDiscoverer.Builder { - private final String folderName; - private String fileNameMatcher = "(.+).jar$"; - private boolean searchRecursively = false; - private Predicate directoryFilter = s -> true; - - public BuilderImpl(String folderName) { - this.folderName = folderName; - } - - @Override - public Builder fileNameMatcher(String pattern) { - this.fileNameMatcher = pattern; - return this; - } - - @Override - public Builder searchRecursively(boolean searchRecursively) { - this.searchRecursively = searchRecursively; - return this; - } - - @Override - public Builder directoryFilter(Predicate filter) { - this.directoryFilter = filter; - return this; - } - - @Override - public ModDiscoverer build() { - return new ModDiscovererImpl(folderName, Pattern.compile(fileNameMatcher), searchRecursively, directoryFilter); - } - } -} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModRemappingAPIImpl.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModRemappingAPIImpl.java index 7f14a01..b4450eb 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModRemappingAPIImpl.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModRemappingAPIImpl.java @@ -63,7 +63,7 @@ public static void init() { } } - public static ModRemapperContext getCurrentContext() { + public static ModRemapperContext getCurrentContext() { return CURRENT_CONTEXT; } } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java index 5343349..f75ddac 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java @@ -1,5 +1,6 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl.context.v2; +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModDiscovererConfig; import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModRemapper; import io.github.fabriccompatibiltylayers.modremappingapi.impl.LibraryHandler; import io.github.fabriccompatibiltylayers.modremappingapi.impl.ModCandidate; @@ -42,9 +43,21 @@ public void afterRemap() { @Override public List discoverMods(boolean remapClassEdits) { + List collected = new ArrayList<>(); + List candidates = new ArrayList<>(); + for (ModRemapper remapper : remappers) { + for (ModDiscovererConfig config : remapper.getModDiscoverers()) { + V2ModDiscoverer discoverer = new V2ModDiscoverer(config); + candidates.addAll(discoverer.collect()); + } + } + for (ModRemapper remapper : remappers) { + collected.addAll(remapper.collectSubRemappers(candidates)); } + + return collected; } @Override diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2ModDiscoverer.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2ModDiscoverer.java new file mode 100644 index 0000000..8ca854d --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2ModDiscoverer.java @@ -0,0 +1,66 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.impl.context.v2; + +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModCandidate; +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModDiscovererConfig; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils; +import net.fabricmc.loader.api.FabricLoader; + +import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; + +public class V2ModDiscoverer { + private final ModDiscovererConfig config; + + public V2ModDiscoverer(ModDiscovererConfig config) { + this.config = config; + } + + public List collect() { + Path folder = FabricLoader.getInstance().getGameDir().resolve(config.getFolderName()); + + if (!Files.isDirectory(folder)) return new ArrayList<>(); + + List candidates = new ArrayList<>(); + + try { + searchDir(candidates, folder); + } catch (IOException e) { + throw new RuntimeException(e); + } + + return candidates; + } + + private void searchDir(List candidates, Path dir) throws IOException { + try (DirectoryStream stream = Files.newDirectoryStream(dir)) { + for (Path path : stream) { + String name = path.getFileName().toString(); + + if (Files.isDirectory(path)) { + if (config.searchRecursively()) { + if (config.getDirectoryFilter().test(name)) searchDir(candidates, path); + } else { + // TODO Add directory mods support + } + } else if (Files.exists(path)) { + Matcher matcher = config.getFileNameMatcher().matcher(name); + + if (matcher.matches()) { + discoverFileMods(candidates, path); + } + } + } + } + } + + private void discoverFileMods(List candidates, Path modPath) throws IOException { + List entries = FileUtils.listZipContent(modPath); + + candidates.addAll(config.getCandidateCollector().apply(modPath, entries)); + } +} From 614239c642de515b55c4e98d4d7bc157036d5251 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Thu, 3 Apr 2025 00:34:58 +0200 Subject: [PATCH 03/14] More progress on v2 api --- build.gradle | 8 ++ .../api/v2/MappingsConfig.java | 18 +++++ .../modremappingapi/api/v2/ModCandidate.java | 8 ++ .../api/v2/ModDiscovererConfig.java | 2 + .../modremappingapi/api/v2/ModRemapper.java | 3 + .../api/v2}/RemappingFlags.java | 2 +- .../impl/DefaultMappingsConfig.java | 25 ++++++ .../impl/DefaultModCandidate.java | 46 ++++++++++- .../impl/ModDiscovererConfigImpl.java | 20 ++++- .../impl/ModRemappingAPIImpl.java | 5 +- .../impl/context/BaseModRemapperContext.java | 8 ++ .../context/MappingsRegistryInstance.java | 13 +++- .../impl/context/ModRemapperContext.java | 5 +- .../impl/context/v1/ModRemapperV1Context.java | 9 +-- .../impl/context/v2/ModRemmaperV2Context.java | 77 ++++++++++++++++--- .../impl/context/v2/V2ModDiscoverer.java | 45 ++++++++++- .../impl/mappings/MappingsRegistry.java | 2 +- .../impl/remapper/ModTrRemapper.java | 31 ++++---- 18 files changed, 284 insertions(+), 43 deletions(-) create mode 100644 src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingsConfig.java rename src/main/java/io/github/{fabriccompatibiltylayers/modremappingapi/impl/remapper => fabriccompatibilitylayers/modremappingapi/api/v2}/RemappingFlags.java (63%) create mode 100644 src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultMappingsConfig.java diff --git a/build.gradle b/build.gradle index 3bdaab2..a491a6e 100644 --- a/build.gradle +++ b/build.gradle @@ -163,3 +163,11 @@ Now allow ModRemappers to disable mixin remapping which is enabled by default fo embedded.version "spasm", project.spasm_version } } + +task testmodJar(type: Jar) { + from sourceSets.test.output + destinationDirectory = project.layout.buildDirectory.dir("libs") + archiveClassifier.set("testmod") +} + +build.dependsOn testmodJar \ No newline at end of file diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingsConfig.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingsConfig.java new file mode 100644 index 0000000..15f4980 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingsConfig.java @@ -0,0 +1,18 @@ +package io.github.fabriccompatibilitylayers.modremappingapi.api.v2; + +import io.github.fabriccompatibilitylayers.modremappingapi.impl.DefaultMappingsConfig; +import org.jetbrains.annotations.Nullable; + +import java.io.InputStream; +import java.util.Map; +import java.util.function.Supplier; + +public interface MappingsConfig { + @Nullable String getSourceNamespace(); + @Nullable Supplier getExtraMappings(); + Map getRenamingMap(); + + static MappingsConfig defaultConfig() { + return new DefaultMappingsConfig(); + } +} diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModCandidate.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModCandidate.java index 1c9c3c8..c635e13 100644 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModCandidate.java +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModCandidate.java @@ -10,4 +10,12 @@ public interface ModCandidate { String getType(); @Nullable String getAccessWidenerPath(); @Nullable ModCandidate getParent(); + @Nullable String getVersion(); + @Nullable String getParentSubPath(); + String getDestinationName(); + ModDiscovererConfig getDiscovererConfig(); + void setAccessWidener(byte[] data); + byte @Nullable [] getAccessWidener(); + void setDestination(Path destination); + @Nullable Path getDestination(); } diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModDiscovererConfig.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModDiscovererConfig.java index 5020e0b..446b838 100644 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModDiscovererConfig.java +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModDiscovererConfig.java @@ -18,12 +18,14 @@ static Builder builder(String folderName) { boolean searchRecursively(); Predicate getDirectoryFilter(); BiFunction, List> getCandidateCollector(); + boolean getExportToOriginalFolder(); interface Builder { Builder fileNameMatcher(String pattern); Builder searchRecursively(boolean searchRecursively); Builder directoryFilter(Predicate filter); Builder candidateCollector(BiFunction, List> collector); + Builder exportToOriginalFolder(boolean exportToOriginalFolder); ModDiscovererConfig build(); } diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java index 34e8de1..b51291c 100644 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java @@ -7,4 +7,7 @@ public interface ModRemapper { List getModDiscoverers(); List collectSubRemappers(List discoveredMods); + MappingsConfig getMappingsConfig(); + List getRemappingFlags(); + void afterRemapping(); } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/RemappingFlags.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/RemappingFlags.java similarity index 63% rename from src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/RemappingFlags.java rename to src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/RemappingFlags.java index 06446b6..16d1e4b 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/RemappingFlags.java +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/RemappingFlags.java @@ -1,4 +1,4 @@ -package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper; +package io.github.fabriccompatibilitylayers.modremappingapi.api.v2; import org.jetbrains.annotations.ApiStatus; diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultMappingsConfig.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultMappingsConfig.java new file mode 100644 index 0000000..ec99c0c --- /dev/null +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultMappingsConfig.java @@ -0,0 +1,25 @@ +package io.github.fabriccompatibilitylayers.modremappingapi.impl; + +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.MappingsConfig; + +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; + +public class DefaultMappingsConfig implements MappingsConfig { + @Override + public String getSourceNamespace() { + return "official"; + } + + @Override + public Supplier getExtraMappings() { + return null; + } + + @Override + public Map getRenamingMap() { + return new HashMap<>(); + } +} diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultModCandidate.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultModCandidate.java index f3ebdea..cd9741f 100644 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultModCandidate.java +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultModCandidate.java @@ -1,6 +1,7 @@ package io.github.fabriccompatibilitylayers.modremappingapi.impl; import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModCandidate; +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModDiscovererConfig; import org.jetbrains.annotations.Nullable; import java.nio.file.Path; @@ -8,10 +9,13 @@ public class DefaultModCandidate implements ModCandidate { private final String id; private final Path path; + private final ModDiscovererConfig discovererConfig; + private Path destination; - public DefaultModCandidate(Path path) { + public DefaultModCandidate(Path path, ModDiscovererConfig discovererConfig) { this.id = path.getFileName().toString().replace(".jar", "").replace(".zip", "").replace(" ", "_"); this.path = path; + this.discovererConfig = discovererConfig; } @Override @@ -38,4 +42,44 @@ public String getType() { public @Nullable ModCandidate getParent() { return null; } + + @Override + public @Nullable String getVersion() { + return null; + } + + @Override + public @Nullable String getParentSubPath() { + return null; + } + + @Override + public String getDestinationName() { + return this.path.getFileName().toString(); + } + + @Override + public ModDiscovererConfig getDiscovererConfig() { + return discovererConfig; + } + + @Override + public void setAccessWidener(byte[] data) { + + } + + @Override + public byte @Nullable [] getAccessWidener() { + return null; + } + + @Override + public void setDestination(Path destination) { + this.destination = destination; + } + + @Override + public Path getDestination() { + return this.destination; + } } diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/ModDiscovererConfigImpl.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/ModDiscovererConfigImpl.java index ceaca59..1375a53 100644 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/ModDiscovererConfigImpl.java +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/ModDiscovererConfigImpl.java @@ -19,13 +19,15 @@ public class ModDiscovererConfigImpl implements ModDiscovererConfig { private final boolean searchRecursively; private final Predicate directoryFilter; private final @Nullable BiFunction, List> candidateCollector; + private final boolean exportToOriginalFolder; - private ModDiscovererConfigImpl(String folderName, Pattern fileNameMatcher, boolean searchRecursively, Predicate directoryFilter, @Nullable BiFunction, List> candidateCollector) { + private ModDiscovererConfigImpl(String folderName, Pattern fileNameMatcher, boolean searchRecursively, Predicate directoryFilter, @Nullable BiFunction, List> candidateCollector, boolean exportToOriginalFolder) { this.folderName = folderName; this.fileNameMatcher = fileNameMatcher; this.searchRecursively = searchRecursively; this.directoryFilter = directoryFilter; this.candidateCollector = candidateCollector; + this.exportToOriginalFolder = exportToOriginalFolder; } @Override @@ -53,12 +55,17 @@ public BiFunction, List> getCandidateCollector( return this.candidateCollector == null ? this::defaultCandidateCollector : this.candidateCollector; } + @Override + public boolean getExportToOriginalFolder() { + return this.exportToOriginalFolder; + } + private List defaultCandidateCollector(Path modPath, List fileList) { List candidates = new ArrayList<>(); for (String file : fileList) { if (file.endsWith(".class")) { - candidates.add(new DefaultModCandidate(modPath)); + candidates.add(new DefaultModCandidate(modPath, this)); break; } } @@ -72,6 +79,7 @@ public static class BuilderImpl implements ModDiscovererConfig.Builder { private boolean searchRecursively = false; private Predicate directoryFilter = s -> true; private BiFunction, List> candidateCollector; + private boolean exportToOriginalFolder = false; public BuilderImpl(String folderName) { this.folderName = folderName; @@ -101,9 +109,15 @@ public Builder candidateCollector(BiFunction, List v2Keys = new ArrayList<>(v2Remappers.keySet()); - for (String contextKey : v2Keys) { + while (!v2Keys.isEmpty()) { + String contextKey = v2Keys.remove(0); ModRemmaperV2Context context = new ModRemmaperV2Context(contextKey, v2Remappers.get(contextKey)); CURRENT_CONTEXT = context; + CURRENT_CONTEXT.init(); + Map> newRemappers = context.discoverMods(remapClassEdits) .stream().collect(Collectors.groupingBy(ModRemapper::getContextId)); diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/BaseModRemapperContext.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/BaseModRemapperContext.java index c516880..dbb5854 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/BaseModRemapperContext.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/BaseModRemapperContext.java @@ -6,11 +6,19 @@ public abstract class BaseModRemapperContext implements ModRemapperContext { private static final Map REGISTRY = new HashMap<>(); + public final String contextId; + public BaseModRemapperContext(String id) { REGISTRY.put(id, this); + this.contextId = id; } public static ModRemapperContext get(String id) { return REGISTRY.get(id); } + + @Override + public String getId() { + return this.contextId; + } } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MappingsRegistryInstance.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MappingsRegistryInstance.java index 30c2784..4853725 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MappingsRegistryInstance.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MappingsRegistryInstance.java @@ -11,6 +11,7 @@ import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.VersionHelper; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.mappingio.MappingVisitor; +import net.fabricmc.mappingio.adapter.MappingNsRenamer; import net.fabricmc.mappingio.tree.MappingTree; import net.fabricmc.mappingio.tree.MemoryMappingTree; @@ -80,9 +81,19 @@ public MemoryMappingTree getFormattedMappings() { } @Override - public void addToFormattedMappings(InputStream stream) throws IOException { + public void addToFormattedMappings(InputStream stream, Map renames) throws IOException { MappingTree extra = MappingTreeHelper.readMappings(stream); + if (!renames.isEmpty()) { + MemoryMappingTree renamed = new MemoryMappingTree(); + + MappingNsRenamer renamer = new MappingNsRenamer(renamed, renames); + + extra.accept(renamer); + + extra = renamed; + } + formatted = MappingTreeHelper.mergeIntoNew(formatted, extra); } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/ModRemapperContext.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/ModRemapperContext.java index 3ac7f14..d664a61 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/ModRemapperContext.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/ModRemapperContext.java @@ -1,9 +1,9 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl.context; +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModCandidate; 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 io.github.fabriccompatibilitylayers.modremappingapi.api.v2.RemappingFlags; import net.fabricmc.tinyremapper.TinyRemapper; import java.nio.file.Path; @@ -22,4 +22,5 @@ public interface ModRemapperContext { void addToRemapperBuilder(TinyRemapper.Builder builder); Set getRemappingFlags(); LibraryHandler getLibraryHandler(); + String getId(); } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java index fd5356b..0692aad 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java @@ -7,10 +7,9 @@ import io.github.fabriccompatibiltylayers.modremappingapi.impl.compatibility.V0ModRemapper; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.BaseModRemapperContext; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.MappingsRegistryInstance; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.ModRemapperContext; import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.ModTrRemapper; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.RemappingFlags; +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.RemappingFlags; import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.SoftLockFixer; import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor.MRAApplyVisitor; import net.fabricmc.loader.api.FabricLoader; @@ -52,7 +51,7 @@ public void init() { mappings.ifPresent(inputStreamSupplier -> { try { - this.mappingsRegistry.addToFormattedMappings(inputStreamSupplier.get()); + this.mappingsRegistry.addToFormattedMappings(inputStreamSupplier.get(), new HashMap<>()); } catch (IOException e) { throw new RuntimeException(e); } @@ -77,7 +76,7 @@ public void init() { this.mappingsRegistry.generateAdditionalMappings(); } - public void remapMods(Map pathMap) { + public void remapMods(Map pathMap) { Constants.MAIN_LOGGER.debug("Starting jar remapping!"); SoftLockFixer.preloadClasses(); TinyRemapper remapper = ModTrRemapper.makeRemapper(this); @@ -103,7 +102,7 @@ public List discoverMods(boolean remapClassEdits) { mappingsRegistry.generateModMappings(); - this.remapMods(modPaths); +// this.remapMods(modPaths); modPaths.values().forEach(FabricLauncherBase.getLauncher()::addToClassPath); diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java index f75ddac..fdd5782 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java @@ -1,18 +1,19 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl.context.v2; -import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModDiscovererConfig; -import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModRemapper; +import fr.catcore.modremapperapi.utils.Constants; +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.*; import io.github.fabriccompatibiltylayers.modremappingapi.impl.LibraryHandler; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.ModCandidate; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.BaseModRemapperContext; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.MappingsRegistryInstance; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.ModRemapperContext; import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.RemappingFlags; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.ModTrRemapper; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.SoftLockFixer; import net.fabricmc.tinyremapper.TinyRemapper; +import java.io.IOException; import java.nio.file.Path; import java.util.*; +import java.util.stream.Collectors; public class ModRemmaperV2Context extends BaseModRemapperContext { private final List remappers; @@ -28,27 +29,64 @@ public ModRemmaperV2Context(String id, List remappers) { @Override public void init() { + for (ModRemapper remapper : remappers) { + MappingsConfig mappings = remapper.getMappingsConfig(); + + if (mappings.getSourceNamespace() != null) { + this.mappingsRegistry.setSourceNamespace(mappings.getSourceNamespace()); + } + + if (mappings.getExtraMappings() != null) { + try { + this.mappingsRegistry.addToFormattedMappings(mappings.getExtraMappings().get(), mappings.getRenamingMap()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + remapFlags.addAll(remapper.getRemappingFlags()); + } + + try { + this.mappingsRegistry.completeFormattedMappings(); + } catch (IOException e) { + throw new RuntimeException(e); + } + libraryHandler.init(this.mappingsRegistry.getSourceNamespace()); + + this.mappingsRegistry.generateAdditionalMappings(); } @Override public void remapMods(Map 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); + Constants.MAIN_LOGGER.debug("Jar remapping done!"); + + this.mappingsRegistry.writeFullMappings(); } @Override public void afterRemap() { - + for (ModRemapper remapper : remappers) { + remapper.afterRemapping(); + } } @Override public List discoverMods(boolean remapClassEdits) { List collected = new ArrayList<>(); - List candidates = new ArrayList<>(); + List candidates = new ArrayList<>(); + Map config2Discoverer = new HashMap<>(); for (ModRemapper remapper : remappers) { for (ModDiscovererConfig config : remapper.getModDiscoverers()) { - V2ModDiscoverer discoverer = new V2ModDiscoverer(config); + V2ModDiscoverer discoverer = new V2ModDiscoverer(this.contextId, config); + config2Discoverer.put(config, discoverer); candidates.addAll(discoverer.collect()); } } @@ -57,6 +95,27 @@ public List discoverMods(boolean remapClassEdits) { collected.addAll(remapper.collectSubRemappers(candidates)); } + Map> config2Candidates = + candidates.stream().collect(Collectors.groupingBy(ModCandidate::getDiscovererConfig)); + + for (ModCandidate candidate : candidates) { + mappingsRegistry.addModMappings(candidate.getPath()); + } + + mappingsRegistry.generateModMappings(); + + Map candidateToOutput = new HashMap<>(); + + for (Map.Entry> entry : config2Candidates.entrySet()) { + ModDiscovererConfig config = entry.getKey(); + + candidateToOutput.putAll( + config2Discoverer.get(config).computeDestinations(entry.getValue()) + ); + } + + if (!candidateToOutput.isEmpty()) this.remapMods(candidateToOutput); + return collected; } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2ModDiscoverer.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2ModDiscoverer.java index 8ca854d..0bf1e56 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2ModDiscoverer.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2ModDiscoverer.java @@ -2,6 +2,7 @@ import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModCandidate; import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModDiscovererConfig; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.CacheUtils; import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils; import net.fabricmc.loader.api.FabricLoader; @@ -11,24 +12,29 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.regex.Matcher; +import java.util.stream.Collectors; public class V2ModDiscoverer { + private final String contextId; private final ModDiscovererConfig config; + private Path originalDirectory; - public V2ModDiscoverer(ModDiscovererConfig config) { + public V2ModDiscoverer(String contextId, ModDiscovererConfig config) { + this.contextId = contextId; this.config = config; } public List collect() { - Path folder = FabricLoader.getInstance().getGameDir().resolve(config.getFolderName()); + originalDirectory = FabricLoader.getInstance().getGameDir().resolve(config.getFolderName()); - if (!Files.isDirectory(folder)) return new ArrayList<>(); + if (!Files.isDirectory(originalDirectory)) return new ArrayList<>(); List candidates = new ArrayList<>(); try { - searchDir(candidates, folder); + searchDir(candidates, originalDirectory); } catch (IOException e) { throw new RuntimeException(e); } @@ -63,4 +69,35 @@ private void discoverFileMods(List candidates, Path modPath) throw candidates.addAll(config.getCandidateCollector().apply(modPath, entries)); } + + public Map computeDestinations(List candidates) { + Path destination; + + if (config.getExportToOriginalFolder()) { + destination = originalDirectory; + } else { + destination = CacheUtils.getCachePath(this.contextId + "/" + config.getFolderName()); + } + + if (!Files.exists(destination)) { + try { + Files.createDirectories(destination); + } catch (IOException e) { + throw new RuntimeException(e); + } + } else if (!config.getExportToOriginalFolder()) { + FileUtils.emptyDir(destination); + } + + Path finalDestination = destination; + + return candidates.stream().collect(Collectors.toMap( + candidate -> candidate, + candidate -> { + Path modDestination = finalDestination.resolve(candidate.getDestinationName()); + candidate.setDestination(modDestination); + return modDestination; + } + )); + } } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/mappings/MappingsRegistry.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/mappings/MappingsRegistry.java index 0d42728..3c83517 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/mappings/MappingsRegistry.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/mappings/MappingsRegistry.java @@ -43,7 +43,7 @@ public abstract class MappingsRegistry { public abstract List getVanillaClassNames(); public abstract MemoryMappingTree getFormattedMappings(); - public abstract void addToFormattedMappings(InputStream stream) throws IOException; + public abstract void addToFormattedMappings(InputStream stream, Map renames) throws IOException; public abstract void completeFormattedMappings() throws IOException; public abstract void addModMappings(Path path); public abstract void generateModMappings(); diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/ModTrRemapper.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/ModTrRemapper.java index 4e76089..826466c 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/ModTrRemapper.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/ModTrRemapper.java @@ -1,6 +1,7 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.ModCandidate; +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModCandidate; +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.RemappingFlags; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.ModRemapperContext; import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingTreeHelper; import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; @@ -72,7 +73,7 @@ public static TinyRemapper makeRemapper(ModRemapperContext context) { return remapper; } - public static void remapMods(TinyRemapper remapper, Map paths, ModRemapperContext context) { + public static void remapMods(TinyRemapper remapper, Map paths, ModRemapperContext context) { List outputConsumerPaths = new ArrayList<>(); List resourceRemappers = new ArrayList<>(NonClassCopyMode.FIX_META_INF.remappers); @@ -82,7 +83,7 @@ public static void remapMods(TinyRemapper remapper, Map path TrRemapperHelper.applyRemapper( remapper, - paths.entrySet().stream().collect(Collectors.toMap(entry -> entry.getKey().original, Map.Entry::getValue)), + paths.entrySet().stream().collect(Collectors.toMap(entry -> entry.getKey().getPath(), Map.Entry::getValue)), outputConsumerPaths, resourceRemappers, true, @@ -92,35 +93,35 @@ public static void remapMods(TinyRemapper remapper, Map path ); if (context.getRemappingFlags().contains(RemappingFlags.ACCESS_WIDENER)) { - for (Map.Entry entry : paths.entrySet()) { + for (Map.Entry entry : paths.entrySet()) { ModCandidate candidate = entry.getKey(); Path jarPath = entry.getValue(); - if (candidate.accessWidenerName != null && candidate.accessWidener != null) { + if (candidate.getAccessWidenerPath() != null && candidate.getAccessWidener() != null) { try (FileSystem fs = FileUtils.getJarFileSystem(jarPath)) { - Files.delete(fs.getPath(candidate.accessWidenerName)); - Files.write(fs.getPath(candidate.accessWidenerName), candidate.accessWidener); + Files.delete(fs.getPath(candidate.getAccessWidenerPath())); + Files.write(fs.getPath(candidate.getAccessWidenerPath()), candidate.getAccessWidener()); } catch (Throwable t) { - throw new RuntimeException("Error while writing remapped access widener for '" + candidate.modName + "'", t); + throw new RuntimeException("Error while writing remapped access widener for '" + candidate.getId() + "'", t); } } } } } - private static @Nullable Consumer getRemapperConsumer(Map paths, ModRemapperContext context) { + private static @Nullable Consumer getRemapperConsumer(Map paths, ModRemapperContext context) { Consumer consumer = null; if (context.getRemappingFlags().contains(RemappingFlags.ACCESS_WIDENER)) { consumer = (currentRemapper) -> { - for (Map.Entry entry : paths.entrySet()) { - ModCandidate candidate = entry.getKey(); + for (Map.Entry entry : paths.entrySet()) { + io.github.fabriccompatibilitylayers.modremappingapi.api.v2.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()); + if (candidate.getAccessWidenerPath() != null) { + try (FileSystem jarFs = FileUtils.getJarFileSystem(candidate.getPath())) { + candidate.setAccessWidener(remapAccessWidener(Files.readAllBytes(jarFs.getPath(candidate.getAccessWidenerPath())), currentRemapper.getRemapper(), context.getMappingsRegistry().getTargetNamespace())); } catch (Throwable t) { - throw new RuntimeException("Error while remapping access widener for '" + candidate.modName + "'", t); + throw new RuntimeException("Error while remapping access widener for '" + candidate.getId() + "'", t); } } } From 3af7cf710936e6814c933e8cfd6361ea08c88cd6 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sun, 6 Apr 2025 21:20:45 +0200 Subject: [PATCH 04/14] Fix all remaining mixin remapping issues --- .../api/v2/MappingsConfig.java | 3 +- .../impl/DefaultMappingsConfig.java | 3 +- .../context/MappingsRegistryInstance.java | 11 + .../impl/context/MixinData.java | 26 +++ .../impl/context/ModRemapperContext.java | 2 +- .../impl/context/v1/ModRemapperV1Context.java | 13 +- .../impl/context/v2/ModRemmaperV2Context.java | 18 +- .../impl/remapper/ModTrRemapper.java | 60 +++++- .../impl/remapper/SoftLockFixer.java | 8 +- .../impl/remapper/TrRemapperHelper.java | 33 ++- .../asm/mixin/RefmapBaseMixinExtension.java | 74 +++++++ .../impl/remapper/resource/RefmapJson.java | 189 +++++++++++++++++- .../remapper/resource/RefmapRemapper.java | 156 +-------------- ...ava => MixinPostApplyVisitorProvider.java} | 6 +- .../ImprovedHardTargetMixinClassVisitor.java | 82 ++++++++ .../hard/ImprovedMixinAnnotationVisitor.java | 62 ++++++ 16 files changed, 555 insertions(+), 191 deletions(-) create mode 100644 src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MixinData.java create mode 100644 src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/asm/mixin/RefmapBaseMixinExtension.java rename src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/visitor/{MixinPostApplyVisitor.java => MixinPostApplyVisitorProvider.java} (88%) create mode 100644 src/main/java/net/fabricmc/tinyremapper/extension/mixin/hard/ImprovedHardTargetMixinClassVisitor.java create mode 100644 src/main/java/net/fabricmc/tinyremapper/extension/mixin/hard/ImprovedMixinAnnotationVisitor.java diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingsConfig.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingsConfig.java index 15f4980..023b38e 100644 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingsConfig.java +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingsConfig.java @@ -3,13 +3,12 @@ import io.github.fabriccompatibilitylayers.modremappingapi.impl.DefaultMappingsConfig; import org.jetbrains.annotations.Nullable; -import java.io.InputStream; import java.util.Map; import java.util.function.Supplier; public interface MappingsConfig { @Nullable String getSourceNamespace(); - @Nullable Supplier getExtraMappings(); + @Nullable Supplier getExtraMappings(); Map getRenamingMap(); static MappingsConfig defaultConfig() { diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultMappingsConfig.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultMappingsConfig.java index ec99c0c..8b9412f 100644 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultMappingsConfig.java +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultMappingsConfig.java @@ -2,7 +2,6 @@ import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.MappingsConfig; -import java.io.InputStream; import java.util.HashMap; import java.util.Map; import java.util.function.Supplier; @@ -14,7 +13,7 @@ public String getSourceNamespace() { } @Override - public Supplier getExtraMappings() { + public Supplier getExtraMappings() { return null; } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MappingsRegistryInstance.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MappingsRegistryInstance.java index 4853725..327f50e 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MappingsRegistryInstance.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MappingsRegistryInstance.java @@ -12,6 +12,7 @@ import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.mappingio.MappingVisitor; import net.fabricmc.mappingio.adapter.MappingNsRenamer; +import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch; import net.fabricmc.mappingio.tree.MappingTree; import net.fabricmc.mappingio.tree.MemoryMappingTree; @@ -94,6 +95,16 @@ public void addToFormattedMappings(InputStream stream, Map renam extra = renamed; } + if (!Objects.equals(extra.getSrcNamespace(), formatted.getSrcNamespace()) && extra.getDstNamespaces().contains(formatted.getSrcNamespace())) { + MemoryMappingTree switched = new MemoryMappingTree(); + + MappingSourceNsSwitch switcher = new MappingSourceNsSwitch(switched, formatted.getSrcNamespace()); + + extra.accept(switcher); + + extra = switched; + } + formatted = MappingTreeHelper.mergeIntoNew(formatted, extra); } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MixinData.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MixinData.java new file mode 100644 index 0000000..a95e460 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MixinData.java @@ -0,0 +1,26 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.impl.context; + +import net.fabricmc.tinyremapper.InputTag; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class MixinData { + private final Map> mixin2TargetMap = new HashMap<>(); + private final Map> mixinRefmapData = new HashMap<>(); + private final List hardMixins = new ArrayList<>(); + + public Map> getMixin2TargetMap() { + return mixin2TargetMap; + } + + public Map> getMixinRefmapData() { + return mixinRefmapData; + } + + public List getHardMixins() { + return hardMixins; + } +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/ModRemapperContext.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/ModRemapperContext.java index d664a61..53258a1 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/ModRemapperContext.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/ModRemapperContext.java @@ -17,10 +17,10 @@ public interface ModRemapperContext { void afterRemap(); List discoverMods(boolean remapClassEdits); void gatherRemappers(); - Map> getMixin2TargetMap(); MappingsRegistry getMappingsRegistry(); void addToRemapperBuilder(TinyRemapper.Builder builder); Set getRemappingFlags(); LibraryHandler getLibraryHandler(); String getId(); + MixinData getMixinData(); } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java index 0692aad..a41b574 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java @@ -7,6 +7,7 @@ import io.github.fabriccompatibiltylayers.modremappingapi.impl.compatibility.V0ModRemapper; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.BaseModRemapperContext; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.MappingsRegistryInstance; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.MixinData; import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.ModTrRemapper; import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.RemappingFlags; @@ -25,7 +26,7 @@ public class ModRemapperV1Context extends BaseModRemapperContext { private final Set remapFlags = new HashSet<>(); private final List remappers = new ArrayList<>(); - private final Map> mixin2TargetMap = new HashMap<>(); + private final MixinData mixinData = new MixinData(); private final MappingsRegistryInstance mappingsRegistry = new MappingsRegistryInstance(); private final LibraryHandler libraryHandler = new LibraryHandler(); private final V1ModDiscoverer modDiscoverer = new V1ModDiscoverer(); @@ -123,11 +124,6 @@ public void gatherRemappers() { remappers.addAll(FabricLoader.getInstance().getEntrypoints(v1EntrypointName, ModRemapper.class)); } - @Override - public Map> getMixin2TargetMap() { - return mixin2TargetMap; - } - @Override public MappingsRegistry getMappingsRegistry() { return this.mappingsRegistry; @@ -164,4 +160,9 @@ public Set getRemappingFlags() { public LibraryHandler getLibraryHandler() { return libraryHandler; } + + @Override + public MixinData getMixinData() { + return mixinData; + } } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java index fdd5782..a2e8c45 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java @@ -5,12 +5,16 @@ import io.github.fabriccompatibiltylayers.modremappingapi.impl.LibraryHandler; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.BaseModRemapperContext; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.MappingsRegistryInstance; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.MixinData; import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.ModTrRemapper; import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.SoftLockFixer; import net.fabricmc.tinyremapper.TinyRemapper; +import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.StringReader; +import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.util.*; import java.util.stream.Collectors; @@ -18,7 +22,7 @@ public class ModRemmaperV2Context extends BaseModRemapperContext { private final List remappers; private final Set remapFlags = new HashSet<>(); - private final Map> mixin2TargetMap = new HashMap<>(); + private final MixinData mixinData = new MixinData(); private final MappingsRegistryInstance mappingsRegistry = new MappingsRegistryInstance(); private final LibraryHandler libraryHandler = new LibraryHandler(); @@ -38,7 +42,7 @@ public void init() { if (mappings.getExtraMappings() != null) { try { - this.mappingsRegistry.addToFormattedMappings(mappings.getExtraMappings().get(), mappings.getRenamingMap()); + this.mappingsRegistry.addToFormattedMappings(new ByteArrayInputStream(mappings.getExtraMappings().get().getBytes(StandardCharsets.UTF_8)), mappings.getRenamingMap()); } catch (IOException e) { throw new RuntimeException(e); } @@ -124,11 +128,6 @@ public void gatherRemappers() { } - @Override - public Map> getMixin2TargetMap() { - return mixin2TargetMap; - } - @Override public MappingsRegistry getMappingsRegistry() { return mappingsRegistry; @@ -152,4 +151,9 @@ public LibraryHandler getLibraryHandler() { public List getRemappers() { return remappers; } + + @Override + public MixinData getMixinData() { + return mixinData; + } } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/ModTrRemapper.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/ModTrRemapper.java index 826466c..06c1b94 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/ModTrRemapper.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/ModTrRemapper.java @@ -1,13 +1,16 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper; +import com.google.gson.Gson; import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModCandidate; import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.RemappingFlags; 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.asm.mixin.RefmapBaseMixinExtension; import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.minecraft.MinecraftRemapper; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.resource.RefmapJson; import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.resource.RefmapRemapper; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor.MixinPostApplyVisitor; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor.MixinPostApplyVisitorProvider; import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils; import net.fabricmc.accesswidener.AccessWidenerReader; import net.fabricmc.accesswidener.AccessWidenerRemapper; @@ -23,6 +26,7 @@ import org.objectweb.asm.commons.Remapper; import java.io.IOException; +import java.net.URISyntaxException; import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; @@ -55,9 +59,11 @@ public static TinyRemapper makeRemapper(ModRemapperContext context) { context.addToRemapperBuilder(builder); if (context.getRemappingFlags().contains(RemappingFlags.MIXIN)) { - MixinPostApplyVisitor mixinPostApplyVisitor = new MixinPostApplyVisitor(); - builder.extraPostApplyVisitor(mixinPostApplyVisitor); - builder.extension(new MixinExtension(EnumSet.of(MixinExtension.AnnotationTarget.HARD))); + builder.extension(new RefmapBaseMixinExtension(inputTag -> !context.getMixinData().getHardMixins().contains(inputTag))); + + MixinPostApplyVisitorProvider mixinPostApplyVisitorProvider = new MixinPostApplyVisitorProvider(); + builder.extraPostApplyVisitor(mixinPostApplyVisitorProvider); + builder.extension(new MixinExtension(context.getMixinData().getHardMixins()::contains)); } TinyRemapper remapper = builder.build(); @@ -76,8 +82,16 @@ public static TinyRemapper makeRemapper(ModRemapperContext context) { public static void remapMods(TinyRemapper remapper, Map paths, ModRemapperContext context) { List outputConsumerPaths = new ArrayList<>(); - List resourceRemappers = new ArrayList<>(NonClassCopyMode.FIX_META_INF.remappers); - resourceRemappers.add(new RefmapRemapper()); + if (context.getRemappingFlags().contains(RemappingFlags.MIXIN)) { + try { + analyzeRefMaps(paths.keySet(), context); + } catch (IOException | URISyntaxException e) { + throw new RuntimeException(e); + } + } + + List resourcePostRemappers = new ArrayList<>(NonClassCopyMode.FIX_META_INF.remappers); + if (context.getRemappingFlags().contains(RemappingFlags.MIXIN)) resourcePostRemappers.add(new RefmapRemapper()); Consumer consumer = getRemapperConsumer(paths, context); @@ -85,7 +99,7 @@ public static void remapMods(TinyRemapper remapper, Map entry.getKey().getPath(), Map.Entry::getValue)), outputConsumerPaths, - resourceRemappers, + resourcePostRemappers, true, context.getMappingsRegistry().getSourceNamespace(), context.getMappingsRegistry().getTargetNamespace(), @@ -138,4 +152,36 @@ private static byte[] remapAccessWidener(byte[] data, Remapper remapper, String accessWidenerReader.read(data, "intermediary"); return writer.write(); } + + private static Gson GSON = new Gson(); + + private static void analyzeRefMaps(Set candidates, ModRemapperContext context) throws IOException, URISyntaxException { + for (ModCandidate candidate : candidates) { + Path path = candidate.getPath(); + + List files = FileUtils.listPathContent(path); + + List refmaps = new ArrayList<>(); + + for (String file : files) { + if (file.contains("refmap") && file.endsWith(".json")) { + refmaps.add(file); + } + } + + if (!refmaps.isEmpty()) { + try (FileSystem fs = FileUtils.getJarFileSystem(path)) { + for (String refmap : refmaps) { + Path refmapPath = fs.getPath(refmap); + + RefmapJson refmapJson = GSON.fromJson(new String(Files.readAllBytes(refmapPath)), RefmapJson.class); + + refmapJson.remap(context.getMappingsRegistry().getFullMappings(), context.getMappingsRegistry().getSourceNamespace(), context.getMappingsRegistry().getTargetNamespace()); + + context.getMixinData().getMixinRefmapData().putAll(refmapJson.mappings); + } + } + } + } + } } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/SoftLockFixer.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/SoftLockFixer.java index c247ae0..bab6916 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/SoftLockFixer.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/SoftLockFixer.java @@ -70,9 +70,10 @@ public static void preloadClasses() { "fr.catcore.modremapperapi.remapping.VisitorInfos$Type", "io.github.fabriccompatibiltylayers.modremappingapi.impl.DefaultModRemapper", "io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.resource.RefmapJson", - "io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor.MixinPostApplyVisitor", + "io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor.MixinPostApplyVisitorProvider", "io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.asm.MRAClassVisitor", "io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.asm.MRAMethodVisitor", + "io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.asm.mixin.RefmapBaseMixinExtension", "io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor.MRAApplyVisitor", "io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.resource.RefmapRemapper", "io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry", @@ -218,7 +219,10 @@ public static void preloadClasses() { getLibClassName("mappingio", "MappingUtil"), getLibClassName("mappingio", "MappingVisitor"), getLibClassName("mappingio", "MappingWriter"), - getLibClassName("mappingio", "MappingWriter$1") + getLibClassName("mappingio", "MappingWriter$1"), + + getLibClassName("tinyremapper", "extension.mixin.hard.ImprovedHardTargetMixinClassVisitor"), + getLibClassName("tinyremapper", "extension.mixin.hard.ImprovedMixinAnnotationVisitor"), }) { try { Constants.MAIN_LOGGER.debug("Preloading class: " + clazz); diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/TrRemapperHelper.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/TrRemapperHelper.java index 93c666a..2d29e58 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/TrRemapperHelper.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/TrRemapperHelper.java @@ -1,7 +1,9 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper; import fr.catcore.modremapperapi.utils.Constants; +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.RemappingFlags; import io.github.fabriccompatibiltylayers.modremappingapi.impl.ModRemappingAPIImpl; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils; import net.fabricmc.tinyremapper.InputTag; import net.fabricmc.tinyremapper.OutputConsumerPath; import net.fabricmc.tinyremapper.TinyRemapper; @@ -9,19 +11,24 @@ import org.jetbrains.annotations.Nullable; import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.FileSystem; +import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; +import java.util.jar.Attributes; +import java.util.jar.Manifest; @ApiStatus.Internal public class TrRemapperHelper { - public static void applyRemapper(TinyRemapper remapper, Map paths, List outputConsumerPaths, List resourceRemappers, boolean analyzeMapping, String srcNamespace, String targetNamespace) { - applyRemapper(remapper, paths, outputConsumerPaths, resourceRemappers, analyzeMapping, srcNamespace, targetNamespace, null); + public static void applyRemapper(TinyRemapper remapper, Map paths, List outputConsumerPaths, List resourcePostRemappers, boolean analyzeMapping, String srcNamespace, String targetNamespace) { + applyRemapper(remapper, paths, outputConsumerPaths, resourcePostRemappers, analyzeMapping, srcNamespace, targetNamespace, null); } - public static void applyRemapper(TinyRemapper remapper, Map paths, List outputConsumerPaths, List resourceRemappers, boolean analyzeMapping, String srcNamespace, String targetNamespace, @Nullable Consumer action) { + public static void applyRemapper(TinyRemapper remapper, Map paths, List outputConsumerPaths, List resourcePostRemappers, boolean analyzeMapping, String srcNamespace, String targetNamespace, @Nullable Consumer action) { try { Map tagMap = new HashMap<>(); @@ -29,6 +36,11 @@ public static void applyRemapper(TinyRemapper remapper, Map paths, L for (Path input : paths.keySet()) { InputTag tag = remapper.createInputTag(); tagMap.put(input, tag); + + if (ModRemappingAPIImpl.getCurrentContext().getRemappingFlags().contains(RemappingFlags.MIXIN)) { + if (useHardMixinRemap(input)) ModRemappingAPIImpl.getCurrentContext().getMixinData().getHardMixins().add(tag); + } + remapper.readInputsAsync(tag, input); } @@ -43,7 +55,7 @@ public static void applyRemapper(TinyRemapper remapper, Map paths, L remapper.apply(outputConsumer, tagMap.get(entry.getKey())); Constants.MAIN_LOGGER.debug("Add input as non class file!"); - outputConsumer.addNonClassFiles(entry.getKey(), remapper, resourceRemappers); + outputConsumer.addNonClassFiles(entry.getKey(), remapper, resourcePostRemappers); Constants.MAIN_LOGGER.debug("Done 1!"); } @@ -72,4 +84,17 @@ public static void applyRemapper(TinyRemapper remapper, Map paths, L }); } } + + private static boolean useHardMixinRemap(Path inputPath) throws IOException, URISyntaxException { + try (FileSystem fs = FileUtils.getJarFileSystem(inputPath)) { + Path manifestPath = fs.getPath("/META-INF/MANIFEST.MF"); + + if (!Files.exists(manifestPath)) return false; + + Manifest manifest = new Manifest(manifestPath.toUri().toURL().openStream()); + Attributes mainAttributes = manifest.getMainAttributes(); + + return "static".equalsIgnoreCase(mainAttributes.getValue("Fabric-Loom-Mixin-Remap-Type")); + } + } } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/asm/mixin/RefmapBaseMixinExtension.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/asm/mixin/RefmapBaseMixinExtension.java new file mode 100644 index 0000000..ddcffe4 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/asm/mixin/RefmapBaseMixinExtension.java @@ -0,0 +1,74 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.asm.mixin; + +import net.fabricmc.tinyremapper.InputTag; +import net.fabricmc.tinyremapper.TinyRemapper; +import net.fabricmc.tinyremapper.api.TrEnvironment; +import net.fabricmc.tinyremapper.extension.mixin.common.data.CommonData; +import net.fabricmc.tinyremapper.extension.mixin.hard.ImprovedHardTargetMixinClassVisitor; +import org.objectweb.asm.ClassVisitor; + +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.function.Consumer; +import java.util.function.Predicate; + +public class RefmapBaseMixinExtension implements TinyRemapper.Extension { + private final Map>> tasks; + private final Predicate inputTagFilter; + + public RefmapBaseMixinExtension(Predicate inputTagFilter) { + this.tasks = new ConcurrentHashMap<>(); + this.inputTagFilter = inputTagFilter; + } + + @Override + public void attach(TinyRemapper.Builder builder) { + builder.extraAnalyzeVisitor(new AnalyzeVisitorProvider()).extraStateProcessor(this::stateProcessor); + } + + private void stateProcessor(TrEnvironment environment) { + CommonData data = new CommonData(environment); + + for (Consumer task : tasks.getOrDefault(environment.getMrjVersion(), Collections.emptyList())) { + try { + task.accept(data); + } catch (RuntimeException e) { + environment.getLogger().error(e.getMessage()); + } + } + } + + private final class AnalyzeVisitorProvider implements TinyRemapper.AnalyzeVisitorProvider { + @Override + public ClassVisitor insertAnalyzeVisitor(int mrjVersion, String className, ClassVisitor next) { + return new ImprovedHardTargetMixinClassVisitor(tasks.computeIfAbsent(mrjVersion, k -> new ConcurrentLinkedQueue<>()), next); + } + + @Override + public ClassVisitor insertAnalyzeVisitor(int mrjVersion, String className, ClassVisitor next, InputTag[] inputTags) { + if (inputTagFilter == null || inputTags == null) { + return insertAnalyzeVisitor(mrjVersion, className, next); + } else { + for (InputTag tag : inputTags) { + if (inputTagFilter.test(tag)) { + return insertAnalyzeVisitor(mrjVersion, className, next); + } + } + + return next; + } + } + + @Override + public ClassVisitor insertAnalyzeVisitor(boolean isInput, int mrjVersion, String className, ClassVisitor next, InputTag[] inputTags) { + if (!isInput) { + return next; + } + + return insertAnalyzeVisitor(mrjVersion, className, next, inputTags); + } + } +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/resource/RefmapJson.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/resource/RefmapJson.java index b09f442..c004b4b 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/resource/RefmapJson.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/resource/RefmapJson.java @@ -1,25 +1,210 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.resource; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.ModRemappingAPIImpl; +import net.fabricmc.mappingio.tree.MappingTree; import net.fabricmc.tinyremapper.TinyRemapper; +import net.fabricmc.tinyremapper.api.TrRemapper; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.stream.Collectors; public class RefmapJson { public final Map> mappings = new HashMap<>(); public final Map>> data = new HashMap<>(); - public void remap(RefmapRemapper remapper, TinyRemapper tiny) { + public void remap(TinyRemapper tiny) { this.data.clear(); // for every class entry we need to remap the mappings of references this.mappings.forEach((mixinClass, refmapEntryMap) -> refmapEntryMap.replaceAll((originalName, oldMappedName) -> - remapper.mapRefMapEntry(mixinClass, oldMappedName, tiny) + mapRefMapEntry(mixinClass, oldMappedName, tiny) ) ); this.data.put("named:intermediary", this.mappings); } + + public void remap(MappingTree tree, String from, String to) { + this.data.clear(); + + this.mappings.forEach((mixinClass, refmapEntryMap) -> refmapEntryMap.entrySet() + .stream().filter(this::filterClass) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)) + .replaceAll((originalName, oldMappedName) -> + mapRefMapEntry(mixinClass, oldMappedName, tree, from, to))); + } + + private boolean filterClass(Map.Entry stringStringEntry) { + String value = stringStringEntry.getValue(); + + return value != null && + value.contains("/") && + !value.contains(";") && + !value.contains(":") && + !value.contains("("); + } + + private String mapRefMapEntry(String mixinClass, String old, MappingTree tree, String from, String to) { + int fromId = tree.getNamespaceId(from); + int toId = tree.getNamespaceId(to); + + return tree.mapClassName(old, fromId, toId); + } + + private String mapRefMapEntry(String mixinClass, String old, TinyRemapper remapper) { + TrRemapper trRemapper = remapper.getEnvironment().getRemapper(); + List supers = ModRemappingAPIImpl.getCurrentContext().getMixinData().getMixin2TargetMap().get(mixinClass); + // format is: + // owner + name + quantifier + (desc == null || desc.startsWith("(") ? "" : ":") + desc + (tail != null ? " -> " : "") + tail + String owner; // can be "" + String name; // can be "" + String quantifier; // can be "" + String desc; // can be "" + String tail; // can be "" + + // read the entry + { + String rest; + // get tail + { + String arrow = " -> "; + int arrowPosition = old.indexOf(arrow); + if (arrowPosition == -1) { // tail == null + tail = ""; + rest = old; + } else { + rest = old.substring(0, arrowPosition); + tail = old.substring(arrowPosition + arrow.length()); + } + } + + // get desc + { + int separatorPosition = rest.indexOf(":"); + if (separatorPosition == -1) { // separator == null + int parenthesisPosition = rest.indexOf("("); + if (parenthesisPosition == -1) { + desc = ""; + } else { + // if there's no ':', then there must be an opening bracket or **the desc is null** + desc = rest.substring(parenthesisPosition); + rest = rest.substring(0, parenthesisPosition); + } + } else { + desc = rest.substring(separatorPosition + 1); + rest = rest.substring(0, separatorPosition); + } + } + + // get owner + { + if (rest.startsWith("L")) { // owner != null + int endPosition = rest.indexOf(";"); + if (endPosition == -1) { + throw new RuntimeException( + "Cannot parse refmap entry of class " + mixinClass + ": it starts with 'L', and doesn't contain a ';': " + old); + } else { + owner = rest.substring(1, endPosition); + rest = rest.substring(endPosition + 1); // we don't want the ';' here + } + } else { + owner = ""; + } + } + + // get quantifier + { + // try to find either '{', '+' or '*' + int bracesPosition = rest.indexOf("{"); + if (bracesPosition == -1) + bracesPosition = rest.indexOf("*"); + if (bracesPosition == -1) + bracesPosition = rest.indexOf("+"); + + if (bracesPosition == -1) { + // try the * and + + quantifier = ""; + } else { + quantifier = rest.substring(bracesPosition); + rest = rest.substring(0, bracesPosition); + } + } + + // get name + { + name = rest; // only name is left +// if (name.isEmpty()) { +// throw new RuntimeException("Cannot parse refmap entry of class " + mixinClass + +// ": the name is \"\", so something went wrong: owner = \"" + owner + "\", name = \"" + name + +// "\", quantifier = \"" + quantifier + "\", desc = \"" + desc + "\", tail = \"" + tail + +// "\", old = \"" + old + "\""); +// } + } + } + + // for now just stop here, most stuff doesn't use quantifiers or tails + if (!quantifier.isEmpty()) + throw new RuntimeException("Quantifiers are not yet supported: " + old); + if (!tail.isEmpty()) + throw new RuntimeException("Tails are not yet supported: " + tail); + + // do the actual mapping + + // it's a class + if (owner.isEmpty() && desc.isEmpty()) { + return trRemapper.map(name); + } + + // it's a method + if (desc.startsWith("(") && desc.contains(")")) { + if (owner.isEmpty()) { // it's an @Invoker + if (supers == null || supers.isEmpty()) { + throw new RuntimeException("Can't find target class for mixin " + mixinClass); + } + + final String originalName = name; + String newDesc = trRemapper.mapMethodDesc(desc); + + if (!originalName.isEmpty()) { + for (String own : supers) { + name = trRemapper.mapMethodName(own, name, desc); + + if (!originalName.equals(name)) { + return name + newDesc; + } + } + } + + return originalName + newDesc; + } else { // just a normal method + return "L" + trRemapper.map(owner) + ";" + trRemapper.mapMethodName(owner, name, desc) + trRemapper.mapMethodDesc(desc); + } + } + + // it's an @Accessor + if (owner.isEmpty()) { + if (supers == null || supers.isEmpty()) { + throw new RuntimeException("Can't find target class for mixin " + mixinClass); + } + + final String originalName = name; + + for (String own : supers) { + name = trRemapper.mapFieldName(own, name, desc); + + if (!originalName.equals(name)) { + return name; + } + } + + return originalName; + } + + // just a normal field + return "L" + trRemapper.map(owner) + ";" + trRemapper.mapFieldName(owner, name, desc) + ":" + trRemapper.mapDesc(desc); + } } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/resource/RefmapRemapper.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/resource/RefmapRemapper.java index 998c92f..e227f02 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/resource/RefmapRemapper.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/resource/RefmapRemapper.java @@ -1,16 +1,13 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.resource; import com.google.gson.Gson; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.ModRemappingAPIImpl; import net.fabricmc.tinyremapper.OutputConsumerPath; import net.fabricmc.tinyremapper.TinyRemapper; -import net.fabricmc.tinyremapper.api.TrRemapper; import java.io.*; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.util.List; public class RefmapRemapper implements OutputConsumerPath.ResourceRemapper { private Gson GSON; @@ -29,7 +26,7 @@ public void transform(Path destinationDirectory, Path relativePath, InputStream RefmapJson json = GSON.fromJson(new InputStreamReader(input), RefmapJson.class); - json.remap(this, remapper); + json.remap(remapper); try (OutputStream os = new BufferedOutputStream(Files.newOutputStream(outputFile))) { DataOutputStream outputStream = new DataOutputStream(os); @@ -37,155 +34,4 @@ public void transform(Path destinationDirectory, Path relativePath, InputStream outputStream.flush(); } } - - public String mapRefMapEntry(String mixinClass, String old, TinyRemapper remapper) { - TrRemapper trRemapper = remapper.getEnvironment().getRemapper(); - List supers = ModRemappingAPIImpl.getCurrentContext().getMixin2TargetMap().get(mixinClass); - // format is: - // owner + name + quantifier + (desc == null || desc.startsWith("(") ? "" : ":") + desc + (tail != null ? " -> " : "") + tail - String owner; // can be "" - String name; - String quantifier; // can be "" - String desc; // can be "" - String tail; // can be "" - - // read the entry - { - String rest; - // get tail - { - String arrow = " -> "; - int arrowPosition = old.indexOf(arrow); - if (arrowPosition == -1) { // tail == null - tail = ""; - rest = old; - } else { - rest = old.substring(0, arrowPosition); - tail = old.substring(arrowPosition + arrow.length()); - } - } - - // get desc - { - int separatorPosition = rest.indexOf(":"); - if (separatorPosition == -1) { // separator == null - int parenthesisPosition = rest.indexOf("("); - if (parenthesisPosition == -1) { - desc = ""; - } else { - // if there's no ':', then there must be an opening bracket or **the desc is null** - desc = rest.substring(parenthesisPosition); - rest = rest.substring(0, parenthesisPosition); - } - } else { - desc = rest.substring(separatorPosition + 1); - rest = rest.substring(0, separatorPosition); - } - } - - // get owner - { - if (rest.startsWith("L")) { // owner != null - int endPosition = rest.indexOf(";"); - if (endPosition == -1) { - throw new RuntimeException( - "Cannot parse refmap entry of class " + mixinClass + ": it starts with 'L', and doesn't contain a ';': " + old); - } else { - owner = rest.substring(1, endPosition); - rest = rest.substring(endPosition + 1); // we don't want the ';' here - } - } else { - owner = ""; - } - } - - // get quantifier - { - // try to find either '{', '+' or '*' - int bracesPosition = rest.indexOf("{"); - if (bracesPosition == -1) - bracesPosition = rest.indexOf("*"); - if (bracesPosition == -1) - bracesPosition = rest.indexOf("+"); - - if (bracesPosition == -1) { - // try the * and + - quantifier = ""; - } else { - quantifier = rest.substring(bracesPosition); - rest = rest.substring(0, bracesPosition); - } - } - - // get name - { - name = rest; // only name is left - if (name.isEmpty()) { - throw new RuntimeException("Cannot parse refmap entry of class " + mixinClass + - ": the name is \"\", so something went wrong: owner = \"" + owner + "\", name = \"" + name + - "\", quantifier = \"" + quantifier + "\", desc = \"" + desc + "\", tail = \"" + tail + - "\", old = \"" + old + "\""); - } - } - } - - // for now just stop here, most stuff doesn't use quantifiers or tails - if (!quantifier.isEmpty()) - throw new RuntimeException("Quantifiers are not yet supported: " + old); - if (!tail.isEmpty()) - throw new RuntimeException("Tails are not yet supported: " + tail); - - // do the actual mapping - - // it's a class - if (owner.isEmpty() && desc.isEmpty()) { - return trRemapper.map(name); - } - - // it's a method - if (desc.startsWith("(") && desc.contains(")")) { - if (owner.isEmpty()) { // it's an @Invoker - if (supers == null || supers.isEmpty()) { - throw new RuntimeException("Can't find target class for mixin " + mixinClass); - } - - final String originalName = name; - String newDesc = trRemapper.mapMethodDesc(desc); - - for (String own : supers) { - name = trRemapper.mapMethodName(own, name, desc); - - if (!originalName.equals(name)) { - return name + newDesc; - } - } - - return originalName + newDesc; - } else { // just a normal method - return "L" + trRemapper.map(owner) + ";" + trRemapper.mapMethodName(owner, name, desc) + trRemapper.mapMethodDesc(desc); - } - } - - // it's an @Accessor - if (owner.isEmpty()) { - if (supers == null || supers.isEmpty()) { - throw new RuntimeException("Can't find target class for mixin " + mixinClass); - } - - final String originalName = name; - - for (String own : supers) { - name = trRemapper.mapFieldName(own, name, desc); - - if (!originalName.equals(name)) { - return name; - } - } - - return originalName; - } - - // just a normal field - return "L" + trRemapper.map(owner) + ";" + trRemapper.mapFieldName(owner, name, desc) + ":" + trRemapper.mapDesc(desc); - } } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/visitor/MixinPostApplyVisitor.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/visitor/MixinPostApplyVisitorProvider.java similarity index 88% rename from src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/visitor/MixinPostApplyVisitor.java rename to src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/visitor/MixinPostApplyVisitorProvider.java index e4b0a7b..98dd7b3 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/visitor/MixinPostApplyVisitor.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/visitor/MixinPostApplyVisitorProvider.java @@ -13,8 +13,8 @@ import java.util.ArrayList; import java.util.List; -public class MixinPostApplyVisitor implements TinyRemapper.ApplyVisitorProvider { - public MixinPostApplyVisitor() {} +public class MixinPostApplyVisitorProvider implements TinyRemapper.ApplyVisitorProvider { + public MixinPostApplyVisitorProvider() {} @Override public ClassVisitor insertApplyVisitor(TrClass cls, ClassVisitor next) { @@ -54,7 +54,7 @@ public ClassVisitor insertApplyVisitor(TrClass cls, ClassVisitor next) { }); } - ModRemappingAPIImpl.getCurrentContext().getMixin2TargetMap().put(cls.getName().replace(".", "/"), supers); + ModRemappingAPIImpl.getCurrentContext().getMixinData().getMixin2TargetMap().put(cls.getName().replace(".", "/"), supers); return next; } diff --git a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/hard/ImprovedHardTargetMixinClassVisitor.java b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/hard/ImprovedHardTargetMixinClassVisitor.java new file mode 100644 index 0000000..c6bcad5 --- /dev/null +++ b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/hard/ImprovedHardTargetMixinClassVisitor.java @@ -0,0 +1,82 @@ +package net.fabricmc.tinyremapper.extension.mixin.hard; + +import net.fabricmc.tinyremapper.extension.mixin.common.MapUtility; +import net.fabricmc.tinyremapper.extension.mixin.common.data.*; +import net.fabricmc.tinyremapper.extension.mixin.hard.annotation.ImplementsAnnotationVisitor; +import net.fabricmc.tinyremapper.extension.mixin.hard.data.SoftInterface; +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.MethodVisitor; + +import java.util.*; +import java.util.function.Consumer; + +public class ImprovedHardTargetMixinClassVisitor extends ClassVisitor { + private final Collection> tasks; + private MxClass _class; + + // @Mixin + private final List targets = new ArrayList<>(); + + // @Implements + private final List interfaces = new ArrayList<>(); + + public ImprovedHardTargetMixinClassVisitor(Collection> tasks, ClassVisitor delegate) { + super(Constant.ASM_VERSION, delegate); + this.tasks = Objects.requireNonNull(tasks); + } + + /** + * This is called before visitAnnotation. + */ + @Override + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { + this._class = new MxClass(name); + super.visit(version, access, name, signature, superName, interfaces); + } + + /** + * This is called before visitMethod & visitField. + */ + @Override + public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { + AnnotationVisitor av = super.visitAnnotation(descriptor, visible); + + if (Annotation.MIXIN.equals(descriptor)) { + av = new ImprovedMixinAnnotationVisitor(av, targets, this._class); + } else if (Annotation.IMPLEMENTS.equals(descriptor)) { + av = new ImplementsAnnotationVisitor(av, interfaces); + } + + return av; + } + + @Override + public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) { + FieldVisitor fv = super.visitField(access, name, descriptor, signature, value); + MxMember field = _class.getField(name, descriptor); + + if (targets.isEmpty()) { + return fv; + } else { + return new HardTargetMixinFieldVisitor(tasks, fv, field, Collections.unmodifiableList(targets)); + } + } + + @Override + public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { + MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions); + MxMember method = _class.getMethod(name, descriptor); + + if (!interfaces.isEmpty() && !MapUtility.IGNORED_NAME.contains(name)) { + ImplementsAnnotationVisitor.visitMethod(tasks, method, interfaces); + } + + if (targets.isEmpty()) { + return mv; + } else { + return new HardTargetMixinMethodVisitor(tasks, mv, method, Collections.unmodifiableList(targets)); + } + } +} diff --git a/src/main/java/net/fabricmc/tinyremapper/extension/mixin/hard/ImprovedMixinAnnotationVisitor.java b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/hard/ImprovedMixinAnnotationVisitor.java new file mode 100644 index 0000000..2ea4306 --- /dev/null +++ b/src/main/java/net/fabricmc/tinyremapper/extension/mixin/hard/ImprovedMixinAnnotationVisitor.java @@ -0,0 +1,62 @@ +package net.fabricmc.tinyremapper.extension.mixin.hard; + +import io.github.fabriccompatibiltylayers.modremappingapi.impl.ModRemappingAPIImpl; +import net.fabricmc.tinyremapper.extension.mixin.common.data.AnnotationElement; +import net.fabricmc.tinyremapper.extension.mixin.common.data.Constant; +import net.fabricmc.tinyremapper.extension.mixin.common.data.MxClass; +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.Type; + +import java.util.HashMap; +import java.util.List; +import java.util.Objects; + +public class ImprovedMixinAnnotationVisitor extends AnnotationVisitor { + private final List targets; + private final MxClass _class; + + public ImprovedMixinAnnotationVisitor(AnnotationVisitor delegate, List targetsOut, MxClass _class) { + super(Constant.ASM_VERSION, delegate); + + this.targets = Objects.requireNonNull(targetsOut); + this._class = Objects.requireNonNull(_class); + } + + @Override + public AnnotationVisitor visitArray(String name) { + AnnotationVisitor visitor = super.visitArray(name); + + if (name.equals(AnnotationElement.TARGETS)) { + return new AnnotationVisitor(Constant.ASM_VERSION, visitor) { + @Override + public void visit(String name, Object value) { + String srcName = ((String) value).replaceAll("\\s", "").replace('.', '/'); + String dstName = srcName; + + srcName = ModRemappingAPIImpl.getCurrentContext().getMixinData() + .getMixinRefmapData() + .getOrDefault(ImprovedMixinAnnotationVisitor.this._class.getName(), new HashMap<>()) + .getOrDefault(value, srcName); + + ImprovedMixinAnnotationVisitor.this.targets.add(srcName); + + value = dstName; + super.visit(name, value); + } + }; + } else if (name.equals(AnnotationElement.VALUE)) { + return new AnnotationVisitor(Constant.ASM_VERSION, visitor) { + @Override + public void visit(String name, Object value) { + Type srcType = Objects.requireNonNull((Type) value); + + ImprovedMixinAnnotationVisitor.this.targets.add(srcType.getInternalName()); + + super.visit(name, value); + } + }; + } else { + return visitor; + } + } +} \ No newline at end of file From 91aa3791f02f93d971bc426d077b66ee1595cb03 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sun, 6 Apr 2025 21:47:46 +0200 Subject: [PATCH 05/14] Fix some mixin accessors not remapping correctly --- .../remapper/visitor/MixinPostApplyVisitorProvider.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/visitor/MixinPostApplyVisitorProvider.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/visitor/MixinPostApplyVisitorProvider.java index 98dd7b3..47461bc 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/visitor/MixinPostApplyVisitorProvider.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/visitor/MixinPostApplyVisitorProvider.java @@ -11,6 +11,7 @@ import org.objectweb.asm.tree.ClassNode; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; public class MixinPostApplyVisitorProvider implements TinyRemapper.ApplyVisitorProvider { @@ -21,6 +22,8 @@ public ClassVisitor insertApplyVisitor(TrClass cls, ClassVisitor next) { ClassNode node = new ClassNode(); cls.accept(node, ClassReader.SKIP_FRAMES); + String className = cls.getName().replace(".", "/"); + List supers = new ArrayList<>(); for (List nodeList : new List[]{ @@ -41,7 +44,8 @@ public ClassVisitor insertApplyVisitor(TrClass cls, ClassVisitor next) { if (val instanceof Type) { theVal = ((Type) val).getInternalName(); } else { - theVal = (String) val; + theVal = ModRemappingAPIImpl.getCurrentContext().getMixinData().getMixinRefmapData() + .getOrDefault(className, new HashMap<>()).getOrDefault((String) val, (String) val); } supers.add(theVal); @@ -54,7 +58,7 @@ public ClassVisitor insertApplyVisitor(TrClass cls, ClassVisitor next) { }); } - ModRemappingAPIImpl.getCurrentContext().getMixinData().getMixin2TargetMap().put(cls.getName().replace(".", "/"), supers); + ModRemappingAPIImpl.getCurrentContext().getMixinData().getMixin2TargetMap().put(className, supers); return next; } From dace5346fea7dee7258d290c2e3f0c59ce135799 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Mon, 7 Apr 2025 21:23:47 +0200 Subject: [PATCH 06/14] Better cache handling --- .../modremapperapi/utils/Constants.java | 7 +++ .../modremappingapi/Dummy.java | 4 -- .../modremappingapi/api/v2/CacheHandler.java | 9 +++ .../modremappingapi/api/v2/ModRemapper.java | 2 + .../impl/InternalCacheHandler.java | 11 ++++ .../context/MappingsRegistryInstance.java | 14 +++-- .../impl/context/v1/ModRemapperV1Context.java | 4 +- .../impl/context/v1/V1CacheHandler.java | 56 +++++++++++++++++ .../impl/context/v2/ModRemmaperV2Context.java | 14 +++-- .../impl/context/v2/V2CacheHandler.java | 60 +++++++++++++++++++ .../impl/context/v2/V2ModDiscoverer.java | 10 ++-- .../impl/utils/CacheUtils.java | 2 +- 12 files changed, 172 insertions(+), 21 deletions(-) delete mode 100644 src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/Dummy.java create mode 100644 src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/CacheHandler.java create mode 100644 src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/InternalCacheHandler.java create mode 100644 src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/V1CacheHandler.java create mode 100644 src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2CacheHandler.java diff --git a/src/main/java/fr/catcore/modremapperapi/utils/Constants.java b/src/main/java/fr/catcore/modremapperapi/utils/Constants.java index e92f42e..26f2225 100644 --- a/src/main/java/fr/catcore/modremapperapi/utils/Constants.java +++ b/src/main/java/fr/catcore/modremapperapi/utils/Constants.java @@ -6,13 +6,20 @@ import java.io.File; public class Constants { + @Deprecated public static final File MAIN_FOLDER = CacheUtils.BASE_FOLDER.toFile(); + @Deprecated public static final File VERSIONED_FOLDER = CacheUtils.MAIN_FOLDER.toFile(); + @Deprecated public static final File LIB_FOLDER = CacheUtils.LIBRARY_FOLDER.toFile(); + @Deprecated public static final File EXTRA_MAPPINGS_FILE = CacheUtils.getCachePath("extra_mappings.tiny").toFile(); + @Deprecated public static final File REMAPPED_MAPPINGS_FILE = CacheUtils.getCachePath("remapped_mappings.tiny").toFile(); + @Deprecated public static final File MC_MAPPINGS_FILE = CacheUtils.getCachePath("mc_mappings.tiny").toFile(); + @Deprecated public static final File FULL_MAPPINGS_FILE = CacheUtils.getCachePath("full_mappings.tiny").toFile(); public static final Logger MAIN_LOGGER = Logger.get("ModRemappingAPI"); diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/Dummy.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/Dummy.java deleted file mode 100644 index 846488d..0000000 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/Dummy.java +++ /dev/null @@ -1,4 +0,0 @@ -package io.github.fabriccompatibilitylayers.modremappingapi; - -public class Dummy { -} diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/CacheHandler.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/CacheHandler.java new file mode 100644 index 0000000..b122e3c --- /dev/null +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/CacheHandler.java @@ -0,0 +1,9 @@ +package io.github.fabriccompatibilitylayers.modremappingapi.api.v2; + +import java.nio.file.Path; + +public interface CacheHandler { + Path resolveTemp(String name); + Path resolveCache(String name); + Path resolveLibrary(String name); +} diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java index b51291c..43df21e 100644 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java @@ -5,6 +5,8 @@ public interface ModRemapper { String getContextId(); + void init(CacheHandler cacheHandler); + List getModDiscoverers(); List collectSubRemappers(List discoveredMods); MappingsConfig getMappingsConfig(); diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/InternalCacheHandler.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/InternalCacheHandler.java new file mode 100644 index 0000000..7fe0e5a --- /dev/null +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/InternalCacheHandler.java @@ -0,0 +1,11 @@ +package io.github.fabriccompatibilitylayers.modremappingapi.impl; + +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.CacheHandler; + +import java.nio.file.Path; + +public interface InternalCacheHandler extends CacheHandler { + Path resolveMappings(String name); + Path resolveRoot(String name); + Path getTempDirectory(); +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MappingsRegistryInstance.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MappingsRegistryInstance.java index 327f50e..63d883f 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MappingsRegistryInstance.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MappingsRegistryInstance.java @@ -2,6 +2,7 @@ import fr.catcore.modremapperapi.utils.Constants; import fr.catcore.wfvaio.WhichFabricVariantAmIOn; +import io.github.fabriccompatibilitylayers.modremappingapi.impl.InternalCacheHandler; import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingBuilder; import io.github.fabriccompatibiltylayers.modremappingapi.impl.MappingBuilderImpl; import io.github.fabriccompatibiltylayers.modremappingapi.impl.MappingsUtilsImpl; @@ -30,8 +31,11 @@ public class MappingsRegistryInstance extends MappingsRegistry { private String defaultPackage = ""; private String sourceNamespace = "official"; - public MappingsRegistryInstance() { + private final InternalCacheHandler cacheHandler; + + public MappingsRegistryInstance(InternalCacheHandler cacheHandler) { super(); + this.cacheHandler = cacheHandler; try { this.formatVanillaMappings(); @@ -121,7 +125,7 @@ public void completeFormattedMappings() throws IOException { } try { - MappingTreeHelper.exportMappings(formatted, Constants.MC_MAPPINGS_FILE.toPath()); + MappingTreeHelper.exportMappings(formatted, this.cacheHandler.resolveMappings("mc_mappings.tiny")); } catch (IOException e) { throw new RuntimeException("Error while writing formatted mappings", e); } @@ -151,7 +155,7 @@ public void generateModMappings() { try { mods.visitEnd(); - MappingTreeHelper.exportMappings(mods, Constants.REMAPPED_MAPPINGS_FILE.toPath()); + MappingTreeHelper.exportMappings(mods, this.cacheHandler.resolveMappings("remapped_mappings.tiny")); } catch (IOException e) { throw new RuntimeException("Error while generating mods mappings", e); } @@ -174,7 +178,7 @@ public void generateAdditionalMappings() { additional.visitEnd(); try { - MappingTreeHelper.exportMappings(additional, Constants.EXTRA_MAPPINGS_FILE.toPath()); + MappingTreeHelper.exportMappings(additional, this.cacheHandler.resolveMappings("extra_mappings.tiny")); } catch (IOException e) { throw new RuntimeException("Error while generating remappers mappings", e); } @@ -211,7 +215,7 @@ public String getTargetNamespace() { @Override public void writeFullMappings() { try { - MappingTreeHelper.exportMappings(full, Constants.FULL_MAPPINGS_FILE.toPath()); + MappingTreeHelper.exportMappings(full, this.cacheHandler.resolveMappings("full_mappings.tiny")); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java index a41b574..2816969 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java @@ -1,6 +1,7 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl.context.v1; import fr.catcore.modremapperapi.utils.Constants; +import io.github.fabriccompatibilitylayers.modremappingapi.impl.InternalCacheHandler; import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingBuilder; import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ModRemapper; import io.github.fabriccompatibiltylayers.modremappingapi.impl.*; @@ -27,7 +28,8 @@ public class ModRemapperV1Context extends BaseModRemapperContext { private final Set remapFlags = new HashSet<>(); private final List remappers = new ArrayList<>(); private final MixinData mixinData = new MixinData(); - private final MappingsRegistryInstance mappingsRegistry = new MappingsRegistryInstance(); + private final InternalCacheHandler cacheHandler = new V1CacheHandler(); + private final MappingsRegistryInstance mappingsRegistry = new MappingsRegistryInstance(cacheHandler); private final LibraryHandler libraryHandler = new LibraryHandler(); private final V1ModDiscoverer modDiscoverer = new V1ModDiscoverer(); diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/V1CacheHandler.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/V1CacheHandler.java new file mode 100644 index 0000000..25c2e02 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/V1CacheHandler.java @@ -0,0 +1,56 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.impl.context.v1; + +import io.github.fabriccompatibilitylayers.modremappingapi.impl.InternalCacheHandler; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.CacheUtils; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +public class V1CacheHandler implements InternalCacheHandler { + private final Path contextDirectory = CacheUtils.MAIN_FOLDER; + private final Path tempDirectory = contextDirectory.resolve("temp"); + private final Path libsDirectory = contextDirectory.resolve("libs"); + + public V1CacheHandler() { + for (Path p : new Path[] {tempDirectory, libsDirectory}) { + if (!Files.exists(p)) { + try { + Files.createDirectories(p); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + } + + @Override + public Path resolveMappings(String name) { + return this.resolveRoot(name); + } + + @Override + public Path resolveRoot(String name) { + return contextDirectory.resolve(name); + } + + @Override + public Path getTempDirectory() { + return tempDirectory; + } + + @Override + public Path resolveTemp(String name) { + return tempDirectory.resolve(name); + } + + @Override + public Path resolveCache(String name) { + return null; + } + + @Override + public Path resolveLibrary(String name) { + return libsDirectory.resolve(name); + } +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java index a2e8c45..5abd98d 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java @@ -2,6 +2,7 @@ import fr.catcore.modremapperapi.utils.Constants; import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.*; +import io.github.fabriccompatibilitylayers.modremappingapi.impl.InternalCacheHandler; import io.github.fabriccompatibiltylayers.modremappingapi.impl.LibraryHandler; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.BaseModRemapperContext; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.MappingsRegistryInstance; @@ -9,11 +10,11 @@ import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.ModTrRemapper; import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.SoftLockFixer; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.CacheUtils; import net.fabricmc.tinyremapper.TinyRemapper; import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.StringReader; import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.util.*; @@ -23,17 +24,22 @@ public class ModRemmaperV2Context extends BaseModRemapperContext { private final List remappers; private final Set remapFlags = new HashSet<>(); private final MixinData mixinData = new MixinData(); - private final MappingsRegistryInstance mappingsRegistry = new MappingsRegistryInstance(); + private final MappingsRegistryInstance mappingsRegistry; private final LibraryHandler libraryHandler = new LibraryHandler(); + private final InternalCacheHandler cacheHandler; public ModRemmaperV2Context(String id, List remappers) { super(id); this.remappers = remappers; + this.cacheHandler = new V2CacheHandler(CacheUtils.getCachePath(id)); + this.mappingsRegistry = new MappingsRegistryInstance(this.cacheHandler); } @Override public void init() { for (ModRemapper remapper : remappers) { + remapper.init(this.cacheHandler); + MappingsConfig mappings = remapper.getMappingsConfig(); if (mappings.getSourceNamespace() != null) { @@ -89,7 +95,7 @@ public List discoverMods(boolean remapClassEdits) { for (ModRemapper remapper : remappers) { for (ModDiscovererConfig config : remapper.getModDiscoverers()) { - V2ModDiscoverer discoverer = new V2ModDiscoverer(this.contextId, config); + V2ModDiscoverer discoverer = new V2ModDiscoverer(config); config2Discoverer.put(config, discoverer); candidates.addAll(discoverer.collect()); } @@ -114,7 +120,7 @@ public List discoverMods(boolean remapClassEdits) { ModDiscovererConfig config = entry.getKey(); candidateToOutput.putAll( - config2Discoverer.get(config).computeDestinations(entry.getValue()) + config2Discoverer.get(config).computeDestinations(entry.getValue(), this.cacheHandler) ); } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2CacheHandler.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2CacheHandler.java new file mode 100644 index 0000000..d3278f9 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2CacheHandler.java @@ -0,0 +1,60 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.impl.context.v2; + +import io.github.fabriccompatibilitylayers.modremappingapi.impl.InternalCacheHandler; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +public class V2CacheHandler implements InternalCacheHandler { + private final Path contextDirectory; + private final Path tempDirectory, cacheDirectory, mappingsDirectory, librariesDirectory; + + public V2CacheHandler(Path contextDirectory) { + this.contextDirectory = contextDirectory; + tempDirectory = this.contextDirectory.resolve("temp"); + cacheDirectory = this.contextDirectory.resolve("cache"); + mappingsDirectory = this.contextDirectory.resolve("mappings"); + librariesDirectory = this.contextDirectory.resolve("libraries"); + + for (Path p : new Path[]{tempDirectory, cacheDirectory, mappingsDirectory, librariesDirectory}) { + if (!Files.exists(p)) { + try { + Files.createDirectories(p); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + } + + @Override + public Path resolveTemp(String name) { + return tempDirectory.resolve(name); + } + + @Override + public Path resolveCache(String name) { + return cacheDirectory.resolve(name); + } + + @Override + public Path resolveLibrary(String name) { + return librariesDirectory.resolve(name); + } + + @Override + public Path resolveMappings(String name) { + return mappingsDirectory.resolve(name); + } + + @Override + public Path resolveRoot(String name) { + return this.contextDirectory.resolve(name); + } + + @Override + public Path getTempDirectory() { + return tempDirectory; + } +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2ModDiscoverer.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2ModDiscoverer.java index 0bf1e56..4a895ea 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2ModDiscoverer.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2ModDiscoverer.java @@ -2,7 +2,7 @@ import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModCandidate; import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModDiscovererConfig; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.CacheUtils; +import io.github.fabriccompatibilitylayers.modremappingapi.impl.InternalCacheHandler; import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils; import net.fabricmc.loader.api.FabricLoader; @@ -17,12 +17,10 @@ import java.util.stream.Collectors; public class V2ModDiscoverer { - private final String contextId; private final ModDiscovererConfig config; private Path originalDirectory; - public V2ModDiscoverer(String contextId, ModDiscovererConfig config) { - this.contextId = contextId; + public V2ModDiscoverer(ModDiscovererConfig config) { this.config = config; } @@ -70,13 +68,13 @@ private void discoverFileMods(List candidates, Path modPath) throw candidates.addAll(config.getCandidateCollector().apply(modPath, entries)); } - public Map computeDestinations(List candidates) { + public Map computeDestinations(List candidates, InternalCacheHandler cacheHandler) { Path destination; if (config.getExportToOriginalFolder()) { destination = originalDirectory; } else { - destination = CacheUtils.getCachePath(this.contextId + "/" + config.getFolderName()); + destination = cacheHandler.resolveCache(config.getFolderName()); } if (!Files.exists(destination)) { diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/CacheUtils.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/CacheUtils.java index 04b4350..f80cd60 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/CacheUtils.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/CacheUtils.java @@ -29,7 +29,7 @@ public static Path getLibraryPath(String pathName) { @ApiStatus.Internal public static Map computeLibraryPaths(Collection sourcePaths, String target) { return sourcePaths.stream().collect(Collectors.toMap(p -> p, - p -> CacheUtils.getLibraryPath(target).resolve(p.toFile().getName()))); + p -> CacheUtils.getLibraryPath(target).resolve(p.getFileName()))); } @ApiStatus.Internal From 328c396bc567d7977f4687b88b4f68e92bc30319 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Mon, 7 Apr 2025 22:59:25 +0200 Subject: [PATCH 07/14] Load v1 Mod Remappers again --- .../modremappingapi/api/v2/ModCandidate.java | 1 + .../api/v2/ModDiscovererConfig.java | 11 +- .../impl/DefaultModCandidate.java | 20 +- .../impl/ModDiscovererConfigImpl.java | 38 +++- .../modremappingapi/impl/ModCandidate.java | 26 --- .../V1DefaultModRemapper.java} | 6 +- .../impl/context/v1/ModRemapperV1Context.java | 114 +++++++++++- .../impl/context/v1/V1CacheHandler.java | 2 +- .../impl/context/v1/V1ModDiscoverer.java | 176 ------------------ .../impl/context/v2/V2ModDiscoverer.java | 54 +++++- .../impl/discover/BaseModDiscoverer.java | 99 ---------- .../impl/remapper/SoftLockFixer.java | 1 - src/main/resources/fabric.mod.json | 2 +- 13 files changed, 215 insertions(+), 335 deletions(-) delete mode 100644 src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModCandidate.java rename src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/{DefaultModRemapper.java => compatibility/V1DefaultModRemapper.java} (83%) delete mode 100644 src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/V1ModDiscoverer.java delete mode 100644 src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/discover/BaseModDiscoverer.java diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModCandidate.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModCandidate.java index c635e13..e35596a 100644 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModCandidate.java +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModCandidate.java @@ -18,4 +18,5 @@ public interface ModCandidate { byte @Nullable [] getAccessWidener(); void setDestination(Path destination); @Nullable Path getDestination(); + void setPath(Path path); } diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModDiscovererConfig.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModDiscovererConfig.java index 446b838..57da7b9 100644 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModDiscovererConfig.java +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModDiscovererConfig.java @@ -17,16 +17,23 @@ static Builder builder(String folderName) { Pattern getFileNameMatcher(); boolean searchRecursively(); Predicate getDirectoryFilter(); - BiFunction, List> getCandidateCollector(); + Collector getCandidateCollector(); boolean getExportToOriginalFolder(); + boolean allowDirectoryMods(); interface Builder { Builder fileNameMatcher(String pattern); Builder searchRecursively(boolean searchRecursively); Builder directoryFilter(Predicate filter); - Builder candidateCollector(BiFunction, List> collector); + Builder candidateCollector(Collector collector); Builder exportToOriginalFolder(boolean exportToOriginalFolder); + Builder allowDirectoryMods(boolean allowDirectoryMods); ModDiscovererConfig build(); } + + @FunctionalInterface + interface Collector { + List collect(ModDiscovererConfig config, Path modPath, List entries); + } } diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultModCandidate.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultModCandidate.java index cd9741f..3256828 100644 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultModCandidate.java +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultModCandidate.java @@ -7,15 +7,20 @@ import java.nio.file.Path; public class DefaultModCandidate implements ModCandidate { - private final String id; - private final Path path; + private String sanitizedFileName, id; + private Path path; private final ModDiscovererConfig discovererConfig; private Path destination; public DefaultModCandidate(Path path, ModDiscovererConfig discovererConfig) { - this.id = path.getFileName().toString().replace(".jar", "").replace(".zip", "").replace(" ", "_"); + this.sanitizedFileName = path.getFileName().toString().replace(" ", "_"); + this.id = this.sanitizedFileName.replace(".jar", "").replace(".zip", ""); this.path = path; this.discovererConfig = discovererConfig; + + if (!this.sanitizedFileName.endsWith(".jar") && !this.sanitizedFileName.endsWith(".zip")) { + this.sanitizedFileName += ".zip"; + } } @Override @@ -55,7 +60,7 @@ public String getType() { @Override public String getDestinationName() { - return this.path.getFileName().toString(); + return this.sanitizedFileName; } @Override @@ -82,4 +87,11 @@ public void setDestination(Path destination) { public Path getDestination() { return this.destination; } + + @Override + public void setPath(Path path) { + this.path = path; + } + + } diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/ModDiscovererConfigImpl.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/ModDiscovererConfigImpl.java index 1375a53..c111fe1 100644 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/ModDiscovererConfigImpl.java +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/ModDiscovererConfigImpl.java @@ -18,16 +18,18 @@ public class ModDiscovererConfigImpl implements ModDiscovererConfig { private final Pattern fileNameMatcher; private final boolean searchRecursively; private final Predicate directoryFilter; - private final @Nullable BiFunction, List> candidateCollector; + private final @Nullable Collector candidateCollector; private final boolean exportToOriginalFolder; + private final boolean allowDirectoryMods; - private ModDiscovererConfigImpl(String folderName, Pattern fileNameMatcher, boolean searchRecursively, Predicate directoryFilter, @Nullable BiFunction, List> candidateCollector, boolean exportToOriginalFolder) { + private ModDiscovererConfigImpl(String folderName, Pattern fileNameMatcher, boolean searchRecursively, Predicate directoryFilter, @Nullable Collector candidateCollector, boolean exportToOriginalFolder, boolean allowDirectoryMods) { this.folderName = folderName; this.fileNameMatcher = fileNameMatcher; this.searchRecursively = searchRecursively; this.directoryFilter = directoryFilter; this.candidateCollector = candidateCollector; this.exportToOriginalFolder = exportToOriginalFolder; + this.allowDirectoryMods = allowDirectoryMods; } @Override @@ -51,7 +53,7 @@ public Predicate getDirectoryFilter() { } @Override - public BiFunction, List> getCandidateCollector() { + public Collector getCandidateCollector() { return this.candidateCollector == null ? this::defaultCandidateCollector : this.candidateCollector; } @@ -60,12 +62,12 @@ public boolean getExportToOriginalFolder() { return this.exportToOriginalFolder; } - private List defaultCandidateCollector(Path modPath, List fileList) { + private List defaultCandidateCollector(ModDiscovererConfig config, Path modPath, List fileList) { List candidates = new ArrayList<>(); for (String file : fileList) { if (file.endsWith(".class")) { - candidates.add(new DefaultModCandidate(modPath, this)); + candidates.add(new DefaultModCandidate(modPath, config)); break; } } @@ -73,13 +75,19 @@ private List defaultCandidateCollector(Path modPath, List return candidates; } + @Override + public boolean allowDirectoryMods() { + return allowDirectoryMods; + } + public static class BuilderImpl implements ModDiscovererConfig.Builder { private final String folderName; private String fileNameMatcher = "(.+).jar$"; private boolean searchRecursively = false; private Predicate directoryFilter = s -> true; - private BiFunction, List> candidateCollector; + private Collector candidateCollector; private boolean exportToOriginalFolder = false; + private boolean allowDirectoryMods = false; public BuilderImpl(String folderName) { this.folderName = folderName; @@ -104,7 +112,7 @@ public Builder directoryFilter(Predicate filter) { } @Override - public Builder candidateCollector(BiFunction, List> collector) { + public Builder candidateCollector(Collector collector) { this.candidateCollector = collector; return this; } @@ -115,9 +123,23 @@ public Builder exportToOriginalFolder(boolean exportToOriginalFolder) { return this; } + @Override + public Builder allowDirectoryMods(boolean allowDirectoryMods) { + this.allowDirectoryMods = allowDirectoryMods; + return this; + } + @Override public ModDiscovererConfig build() { - return new ModDiscovererConfigImpl(folderName, Pattern.compile(fileNameMatcher), searchRecursively, directoryFilter, candidateCollector, exportToOriginalFolder); + return new ModDiscovererConfigImpl( + folderName, + Pattern.compile(fileNameMatcher), + searchRecursively, + directoryFilter, + candidateCollector, + exportToOriginalFolder, + allowDirectoryMods + ); } } } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModCandidate.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModCandidate.java deleted file mode 100644 index 3ba9b3f..0000000 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModCandidate.java +++ /dev/null @@ -1,26 +0,0 @@ -package io.github.fabriccompatibiltylayers.modremappingapi.impl; - -import org.jetbrains.annotations.Nullable; - -import java.nio.file.Path; - -public class ModCandidate { - public final String modName; - public final @Nullable String accessWidenerName; - - public final Path file; - public final Path original; - - public byte[] accessWidener; - - public ModCandidate(String modName, @Nullable String accessWidenerName, Path file, Path original) { - this.modName = modName; - this.accessWidenerName = accessWidenerName; - this.file = file; - this.original = original; - } - - public ModCandidate(String modName, Path file, Path original) { - this(modName, null, file, original); - } -} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/DefaultModRemapper.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/compatibility/V1DefaultModRemapper.java similarity index 83% rename from src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/DefaultModRemapper.java rename to src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/compatibility/V1DefaultModRemapper.java index 067aa8f..a6e239a 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/DefaultModRemapper.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/compatibility/V1DefaultModRemapper.java @@ -1,4 +1,4 @@ -package io.github.fabriccompatibiltylayers.modremappingapi.impl; +package io.github.fabriccompatibiltylayers.modremappingapi.impl.compatibility; import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingBuilder; import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ModRemapper; @@ -8,10 +8,10 @@ import java.util.List; -public class DefaultModRemapper implements ModRemapper { +public class V1DefaultModRemapper implements ModRemapper { @Override public String[] getJarFolders() { - return new String[] {"mods"}; + return new String[]{"mods"}; } @Override diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java index 2816969..9a7d003 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java @@ -1,6 +1,9 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl.context.v1; import fr.catcore.modremapperapi.utils.Constants; +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModCandidate; +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModDiscovererConfig; +import io.github.fabriccompatibilitylayers.modremappingapi.impl.DefaultModCandidate; import io.github.fabriccompatibilitylayers.modremappingapi.impl.InternalCacheHandler; import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingBuilder; import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ModRemapper; @@ -9,20 +12,24 @@ import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.BaseModRemapperContext; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.MappingsRegistryInstance; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.MixinData; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.v2.V2ModDiscoverer; import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.ModTrRemapper; import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.RemappingFlags; import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.SoftLockFixer; import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor.MRAApplyVisitor; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils; import net.fabricmc.loader.api.FabricLoader; -import net.fabricmc.loader.impl.launch.FabricLauncherBase; import net.fabricmc.tinyremapper.TinyRemapper; import java.io.IOException; import java.io.InputStream; +import java.net.URISyntaxException; +import java.nio.file.Files; import java.nio.file.Path; import java.util.*; import java.util.function.Supplier; +import java.util.stream.Collectors; public class ModRemapperV1Context extends BaseModRemapperContext { private final Set remapFlags = new HashSet<>(); @@ -31,7 +38,6 @@ public class ModRemapperV1Context extends BaseModRemapperContext { private final InternalCacheHandler cacheHandler = new V1CacheHandler(); private final MappingsRegistryInstance mappingsRegistry = new MappingsRegistryInstance(cacheHandler); private final LibraryHandler libraryHandler = new LibraryHandler(); - private final V1ModDiscoverer modDiscoverer = new V1ModDiscoverer(); public static ModRemapperV1Context INSTANCE; @@ -79,7 +85,7 @@ public void init() { this.mappingsRegistry.generateAdditionalMappings(); } - public void remapMods(Map pathMap) { + public void remapMods(Map pathMap) { Constants.MAIN_LOGGER.debug("Starting jar remapping!"); SoftLockFixer.preloadClasses(); TinyRemapper remapper = ModTrRemapper.makeRemapper(this); @@ -95,23 +101,115 @@ public void afterRemap() { remappers.forEach(ModRemapper::afterRemap); } + private List collectCandidates(ModDiscovererConfig config, Path modPath, List entries) { + boolean fabric = false; + boolean hasClass = false; + + for (String entry : entries) { + if (entry.endsWith("fabric.mod.json") || entry.endsWith("quilt.mod.json") || entry.endsWith("quilt.mod.json5")) { + fabric = true; + break; + } + + if (entry.endsWith(".class")) { + hasClass = true; + } + } + + List list = new ArrayList<>(); + + if (hasClass && !fabric) { + list.add(new DefaultModCandidate(modPath, config)); + } + + return list; + } + @Override public List discoverMods(boolean remapClassEdits) { - Map modPaths = this.modDiscoverer.init(remappers, remapClassEdits, this); + Map> excluded = new HashMap<>(); + + Set modFolders = new HashSet<>(); - for (ModCandidate candidate : modPaths.keySet()) { - mappingsRegistry.addModMappings(candidate.original); + for (ModRemapper remapper : remappers) { + Collections.addAll(modFolders, remapper.getJarFolders()); + + if (remapper instanceof V0ModRemapper) { + excluded.putAll(((V0ModRemapper) remapper).getExclusions()); + } + } + + List candidates = new ArrayList<>(); + Map config2Discoverer = new HashMap<>(); + + for (String modFolder : modFolders) { + ModDiscovererConfig config = ModDiscovererConfig.builder(modFolder) + .fileNameMatcher("(.+).(jar|zip)$") + .candidateCollector(this::collectCandidates) + .build(); + V2ModDiscoverer discoverer = new V2ModDiscoverer(config); + config2Discoverer.put(config, discoverer); + candidates.addAll(discoverer.collect()); + } + + try { + this.handleV0Excluded(candidates, excluded); + } catch (IOException | URISyntaxException e) { + throw new RuntimeException(e); + } + + Map> config2Candidates = + candidates.stream().collect(Collectors.groupingBy(ModCandidate::getDiscovererConfig)); + + for (Map.Entry> entry : config2Candidates.entrySet()) { + ModDiscovererConfig config = entry.getKey(); + + try { + config2Discoverer.get(config).excludeClassEdits(entry.getValue(), this.cacheHandler, this.mappingsRegistry); + } catch (IOException | URISyntaxException e) { + throw new RuntimeException(e); + } + } + + for (ModCandidate candidate : candidates) { + mappingsRegistry.addModMappings(candidate.getPath()); } mappingsRegistry.generateModMappings(); -// this.remapMods(modPaths); + Map candidateToOutput = new HashMap<>(); - modPaths.values().forEach(FabricLauncherBase.getLauncher()::addToClassPath); + for (Map.Entry> entry : config2Candidates.entrySet()) { + ModDiscovererConfig config = entry.getKey(); + + candidateToOutput.putAll( + config2Discoverer.get(config).computeDestinations(entry.getValue(), this.cacheHandler) + ); + } + + if (!candidateToOutput.isEmpty()) this.remapMods(candidateToOutput); + +// modPaths.values().forEach(FabricLauncherBase.getLauncher()::addToClassPath); return new ArrayList<>(); } + private void handleV0Excluded(List mods, Map> excludedMap) throws IOException, URISyntaxException { + for (ModCandidate modCandidate : mods) { + if (excludedMap.containsKey(modCandidate.getId())) { + if (Files.isDirectory(modCandidate.getPath())) { + for (String excluded : excludedMap.get(modCandidate.getId())) { + if (Files.deleteIfExists(modCandidate.getPath().resolve(excluded))) { + Constants.MAIN_LOGGER.debug("File deleted: " + modCandidate.getPath().resolve(excluded)); + } + } + } else { + FileUtils.removeEntriesFromZip(modCandidate.getPath(), excludedMap.get(modCandidate.getId())); + } + } + } + } + private static final String v0EntrypointName = "mod-remapper-api:modremapper"; private static final String v1EntrypointName = "mod-remapper-api:modremapper_v1"; diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/V1CacheHandler.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/V1CacheHandler.java index 25c2e02..a216d4f 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/V1CacheHandler.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/V1CacheHandler.java @@ -46,7 +46,7 @@ public Path resolveTemp(String name) { @Override public Path resolveCache(String name) { - return null; + return this.resolveRoot(name); } @Override diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/V1ModDiscoverer.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/V1ModDiscoverer.java deleted file mode 100644 index 03b0a01..0000000 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/V1ModDiscoverer.java +++ /dev/null @@ -1,176 +0,0 @@ -package io.github.fabriccompatibiltylayers.modremappingapi.impl.context.v1; - -import fr.catcore.modremapperapi.utils.Constants; -import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ModRemapper; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.ModCandidate; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.compatibility.V0ModRemapper; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.discover.BaseModDiscoverer; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.CacheUtils; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils; -import net.fabricmc.loader.api.FabricLoader; -import org.jetbrains.annotations.NotNull; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.*; -import java.util.stream.Collectors; - -public class V1ModDiscoverer extends BaseModDiscoverer { - private final Map> excluded = new HashMap<>(); - - public Map init(List modRemappers, boolean remapClassEdits, ModRemapperV1Context context) { - Set modFolders = new HashSet<>(); - - for (ModRemapper remapper : modRemappers) { - Collections.addAll(modFolders, remapper.getJarFolders()); - - if (remapper instanceof V0ModRemapper) { - excluded.putAll(((V0ModRemapper) remapper).getExclusions()); - } - } - - List mods = new ArrayList<>(); - - for (String jarFolder : modFolders) { - Path mcSubFolder = FabricLoader.getInstance().getGameDir().resolve(jarFolder); - Path cacheFolder = CacheUtils.getCachePath(jarFolder); - - try { - if (!Files.exists(mcSubFolder)) Files.createDirectories(mcSubFolder); - if (!Files.exists(cacheFolder)) Files.createDirectories(cacheFolder); - else FileUtils.emptyDir(cacheFolder); - - mods.addAll(this.discoverMods(mcSubFolder, cacheFolder)); - - this.handleV0Excluded(mods); - } catch (IOException | URISyntaxException e) { - e.printStackTrace(); - } - } - - Path mainTempDir = CacheUtils.getCachePath("temp"); - - if (Files.exists(mainTempDir)) { - FileUtils.emptyDir(mainTempDir); - } - - try { - Files.createDirectory(mainTempDir); - } catch (IOException e) { - throw new RuntimeException(e); - } - - Map modPaths = mods.stream() - .filter(entry -> Files.exists(entry.original)) - .collect(Collectors.toMap(entry -> entry, entry -> entry.file)); - - if (!remapClassEdits) { - modPaths = excludeClassEdits(modPaths, mainTempDir, context.getMappingsRegistry()); - } - - return modPaths; - } - - private void handleV0Excluded(List mods) throws IOException, URISyntaxException { - for (ModCandidate modCandidate : mods) { - if (excluded.containsKey(modCandidate.modName)) { - if (Files.isDirectory(modCandidate.file)) { - 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.modName)); - } - } - } - } - - @Override - public boolean isValidFileName(String fileName) { - return fileName.endsWith(".jar") || fileName.endsWith(".zip"); - } - - @Override - public boolean allowDirectoryMods() { - return true; - } - - @Override - public boolean searchRecursively() { - return false; - } - - @Override - public boolean isValidDirectoryName(String directoryName) { - return false; - } - - @Override - public Optional discoverFolderMod(Path folder, Path destinationFolder) throws IOException { - String name = folder.getFileName().toString().replace(" ", "_"); - Path destination = destinationFolder.resolve(name + ".zip"); - - final boolean[] hasClasses = {false}; - - Files.walkFileTree(folder, new SimpleFileVisitor() { - @Override - public @NotNull FileVisitResult visitFile(Path file, @NotNull BasicFileAttributes attrs) throws IOException { - if (file.toString().endsWith(".class")) { - hasClasses[0] = true; - return FileVisitResult.TERMINATE; - } - - return super.visitFile(file, attrs); - } - }); - - if (hasClasses[0]) { - return Optional.of( - new ModCandidate( - name, - destination, - folder - ) - ); - } - - return Optional.empty(); - } - - @Override - public Optional discoverFileMod(Path file, Path destinationFolder) throws IOException { - String fileName = file.getFileName().toString().replace(" ", "_"); - String modName = fileName.replace(".jar", "").replace(".zip", ""); - - List entries = FileUtils.listZipContent(file); - - boolean found = false; - - for (String entry : entries) { - if (entry.contains("fabric.mod.json")) return Optional.empty(); - - if (entry.endsWith(".class")) { - found = true; - } - } - - if (found) { - return Optional.of( - new ModCandidate( - modName, - destinationFolder.resolve(fileName), - file - ) - ); - } - - return Optional.empty(); - } -} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2ModDiscoverer.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2ModDiscoverer.java index 4a895ea..4850de5 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2ModDiscoverer.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2ModDiscoverer.java @@ -3,10 +3,12 @@ import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModCandidate; import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModDiscovererConfig; import io.github.fabriccompatibilitylayers.modremappingapi.impl.InternalCacheHandler; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils; import net.fabricmc.loader.api.FabricLoader; import java.io.IOException; +import java.net.URISyntaxException; import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; @@ -48,24 +50,55 @@ private void searchDir(List candidates, Path dir) throws IOExcepti if (Files.isDirectory(path)) { if (config.searchRecursively()) { if (config.getDirectoryFilter().test(name)) searchDir(candidates, path); - } else { - // TODO Add directory mods support + } else if (config.allowDirectoryMods()) { + discoverMods(candidates, path); } } else if (Files.exists(path)) { Matcher matcher = config.getFileNameMatcher().matcher(name); if (matcher.matches()) { - discoverFileMods(candidates, path); + discoverMods(candidates, path); } } } } } - private void discoverFileMods(List candidates, Path modPath) throws IOException { - List entries = FileUtils.listZipContent(modPath); + private void discoverMods(List candidates, Path modPath) throws IOException { + List entries = FileUtils.listPathContent(modPath); - candidates.addAll(config.getCandidateCollector().apply(modPath, entries)); + candidates.addAll(config.getCandidateCollector().collect(config, modPath, entries)); + } + + public void excludeClassEdits(List candidates, InternalCacheHandler cacheHandler, MappingsRegistry registry) throws IOException, URISyntaxException { + Path tempDirectory = cacheHandler.resolveTemp(this.config.getFolderName()); + + if (!Files.exists(tempDirectory)) { + try { + Files.createDirectories(tempDirectory); + } catch (IOException e) { + throw new RuntimeException(e); + } + } else { + FileUtils.emptyDir(tempDirectory); + } + + for (ModCandidate candidate : candidates) { + Path modPath = candidate.getPath(); + + String outputName = candidate.getDestinationName(); + Path outputPath = tempDirectory.resolve(outputName); + + if (Files.isDirectory(modPath)) { + FileUtils.zipFolder(modPath, outputPath); + } else { + Files.copy(modPath, outputPath); + } + + FileUtils.removeEntriesFromZip(outputPath, registry.getVanillaClassNames()); + + candidate.setPath(outputPath); + } } public Map computeDestinations(List candidates, InternalCacheHandler cacheHandler) { @@ -94,6 +127,15 @@ public Map computeDestinations(List candidates candidate -> { Path modDestination = finalDestination.resolve(candidate.getDestinationName()); candidate.setDestination(modDestination); + + if (Files.exists(modDestination)) { + try { + Files.delete(modDestination); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return modDestination; } )); diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/discover/BaseModDiscoverer.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/discover/BaseModDiscoverer.java deleted file mode 100644 index f77c0e6..0000000 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/discover/BaseModDiscoverer.java +++ /dev/null @@ -1,99 +0,0 @@ -package io.github.fabriccompatibiltylayers.modremappingapi.impl.discover; - -import io.github.fabriccompatibiltylayers.modremappingapi.impl.ModCandidate; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils; -import org.spongepowered.include.com.google.common.collect.ImmutableList; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.nio.file.DirectoryStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import java.util.*; - -public abstract class BaseModDiscoverer { - public abstract boolean isValidFileName(String fileName); - public abstract boolean allowDirectoryMods(); - public abstract boolean searchRecursively(); - public abstract boolean isValidDirectoryName(String directoryName); - public abstract Optional discoverFolderMod(Path folder, Path destinationFolder) throws IOException; - public abstract Optional discoverFileMod(Path file, Path destinationFolder) throws IOException; - - public List discoverMods(Path folder, Path destination) throws IOException { - List mods = new ArrayList<>(); - - if (!Files.isDirectory(folder)) return ImmutableList.of(); - - try (DirectoryStream stream = Files.newDirectoryStream(folder)) { - for (Path path : stream) { - String name = path.getFileName().toString(); - - if (Files.isDirectory(path)) { - if (searchRecursively() && isValidDirectoryName(name)) { - mods.addAll(discoverMods(folder.resolve(name), destination.resolve(name))); - } else if (allowDirectoryMods()) { - discoverFolderMod(path, destination) - .ifPresent(mods::add); - } - } else if (Files.exists(path) && isValidFileName(name)) { - discoverFileMod(path, destination) - .ifPresent(mods::add); - } - } - } - - return mods; - } - - public Map excludeClassEdits(Map modPaths, Path tempFolder, MappingsRegistry mappingsRegistry) { - Map map = new HashMap<>(); - Map convertMap = new HashMap<>(); - - for (Map.Entry entry : modPaths.entrySet()) { - ModCandidate modCandidate = entry.getKey(); - Path tempDir = tempFolder.resolve(entry.getValue().getParent().getFileName().toString()); - - if (!Files.exists(tempDir)) { - try { - Files.createDirectory(tempDir); - } catch (IOException e) { - e.printStackTrace(); - continue; - } - } - - Path tempFile = tempDir.resolve(entry.getValue().getFileName().toString()); - map.put(new ModCandidate( - modCandidate.modName, - modCandidate.accessWidenerName, - modCandidate.file, - tempFile - ), entry.getValue()); - convertMap.put(entry.getKey(), tempFile); - } - - List errored = new ArrayList<>(); - - for (Map.Entry entry : convertMap.entrySet()) { - ModCandidate modCandidate = entry.getKey(); - try { - if (Files.isDirectory(modCandidate.original)) { - FileUtils.zipFolder(modCandidate.original, entry.getValue()); - } else { - Files.copy(modCandidate.original, entry.getValue(), StandardCopyOption.REPLACE_EXISTING); - } - - FileUtils.removeEntriesFromZip(entry.getValue(), mappingsRegistry.getVanillaClassNames()); - } catch (IOException | URISyntaxException e) { - e.printStackTrace(); - errored.add(modCandidate); - } - } - - errored.forEach(map::remove); - - return map; - } -} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/SoftLockFixer.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/SoftLockFixer.java index bab6916..30d7093 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/SoftLockFixer.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/SoftLockFixer.java @@ -68,7 +68,6 @@ public static void preloadClasses() { "fr.catcore.modremapperapi.remapping.VisitorInfos$MethodNamed", "fr.catcore.modremapperapi.remapping.VisitorInfos$MethodValue", "fr.catcore.modremapperapi.remapping.VisitorInfos$Type", - "io.github.fabriccompatibiltylayers.modremappingapi.impl.DefaultModRemapper", "io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.resource.RefmapJson", "io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor.MixinPostApplyVisitorProvider", "io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.asm.MRAClassVisitor", diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index f44c180..cbc799b 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -23,7 +23,7 @@ "environment": "*", "entrypoints": { "mod-remapper-api:modremapper_v1": [ - "io.github.fabriccompatibiltylayers.modremappingapi.impl.DefaultModRemapper" + "io.github.fabriccompatibiltylayers.modremappingapi.impl.compatibility.V1DefaultModRemapper" ], "spasm:raw_transformer": [ "io.github.fabriccompatibiltylayers.modremappingapi.impl.TransformerRegistry" From 142f4415d6cb1fb447e3d5bfbc87b56f514a9a5b Mon Sep 17 00:00:00 2001 From: Cat Core Date: Mon, 7 Apr 2025 23:31:08 +0200 Subject: [PATCH 08/14] Fix crash with v1 Remappers --- .../modremappingapi/impl/utils/FileUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/FileUtils.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/FileUtils.java index 7713a63..68e698e 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/FileUtils.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/FileUtils.java @@ -164,8 +164,8 @@ public FileVisitResult visitFileFailed(Path file, IOException exc) { } @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - Files.delete(dir); + public FileVisitResult postVisitDirectory(Path subDir, IOException exc) throws IOException { + if (dir != subDir) Files.delete(subDir); return FileVisitResult.CONTINUE; } }); From 4078f4f02734da653fa5f5176a2b27ebad48e54d Mon Sep 17 00:00:00 2001 From: Cat Core Date: Tue, 8 Apr 2025 22:16:32 +0200 Subject: [PATCH 09/14] Fix path encoding issues and Backward compatibility again --- .../modremappingapi/impl/context/v1/ModRemapperV1Context.java | 3 ++- .../modremappingapi/impl/remapper/TrRemapperHelper.java | 2 +- .../modremappingapi/impl/utils/FileUtils.java | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java index 9a7d003..bf778a0 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java @@ -20,6 +20,7 @@ import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor.MRAApplyVisitor; import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils; import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.impl.launch.FabricLauncherBase; import net.fabricmc.tinyremapper.TinyRemapper; import java.io.IOException; @@ -189,7 +190,7 @@ public List discoverMods(boolean remapClassEdits) { if (!candidateToOutput.isEmpty()) this.remapMods(candidateToOutput); -// modPaths.values().forEach(FabricLauncherBase.getLauncher()::addToClassPath); + candidateToOutput.values().forEach(FabricLauncherBase.getLauncher()::addToClassPath); return new ArrayList<>(); } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/TrRemapperHelper.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/TrRemapperHelper.java index 2d29e58..a60acf8 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/TrRemapperHelper.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/TrRemapperHelper.java @@ -91,7 +91,7 @@ private static boolean useHardMixinRemap(Path inputPath) throws IOException, URI if (!Files.exists(manifestPath)) return false; - Manifest manifest = new Manifest(manifestPath.toUri().toURL().openStream()); + Manifest manifest = new Manifest(Files.newInputStream(manifestPath)); Attributes mainAttributes = manifest.getMainAttributes(); return "static".equalsIgnoreCase(mainAttributes.getValue("Fabric-Loom-Mixin-Remap-Type")); diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/FileUtils.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/FileUtils.java index 68e698e..57aea2c 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/FileUtils.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/FileUtils.java @@ -235,7 +235,7 @@ private static void zipFile(File fileToZip, String fileName, ZipOutputStream zip @ApiStatus.Internal public static FileSystem getJarFileSystem(Path path) throws URISyntaxException, IOException { - return FileSystems.newFileSystem(new URI("jar:" + path.toUri()), ZIP_PROPERTIES); + return FileSystems.newFileSystem(URI.create("jar:" + path.toUri()), ZIP_PROPERTIES); } @ApiStatus.Internal From 6e06dd313320f5ff6038a73c502bdeff0406c98c Mon Sep 17 00:00:00 2001 From: Cat Core Date: Tue, 8 Apr 2025 23:12:58 +0200 Subject: [PATCH 10/14] Fully migrate path handling to CacheHandler and add RemapLibrary to v2 api --- .../modremappingapi/api/v2/ModRemapper.java | 5 ++ .../modremappingapi/api/v2/RemapLibrary.java | 26 +++++++ .../impl/DefaultRemapLibrary.java | 54 +++++++++++++++ .../modremappingapi/api/v1/RemapLibrary.java | 23 ++++++- .../modremappingapi/impl/LibraryHandler.java | 68 +++++++++---------- .../impl/ModRemappingAPIImpl.java | 2 + .../impl/context/ModRemapperContext.java | 3 + .../impl/context/v1/ModRemapperV1Context.java | 24 ++++++- .../impl/context/v1/V1CacheHandler.java | 2 +- .../impl/context/v2/ModRemmaperV2Context.java | 21 +++++- .../impl/remapper/ModTrRemapper.java | 12 ++-- .../remapper/minecraft/MinecraftRemapper.java | 25 ++++--- .../impl/utils/CacheUtils.java | 24 +------ 13 files changed, 209 insertions(+), 80 deletions(-) create mode 100644 src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/RemapLibrary.java create mode 100644 src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultRemapLibrary.java diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java index 43df21e..4f76b58 100644 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java @@ -1,5 +1,7 @@ package io.github.fabriccompatibilitylayers.modremappingapi.api.v2; +import net.fabricmc.api.EnvType; + import java.util.List; public interface ModRemapper { @@ -12,4 +14,7 @@ public interface ModRemapper { MappingsConfig getMappingsConfig(); List getRemappingFlags(); void afterRemapping(); + void afterAllRemappings(); + + void addRemappingLibraries(List libraries, EnvType environment); } diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/RemapLibrary.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/RemapLibrary.java new file mode 100644 index 0000000..48187d6 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/RemapLibrary.java @@ -0,0 +1,26 @@ +package io.github.fabriccompatibilitylayers.modremappingapi.api.v2; + +import io.github.fabriccompatibilitylayers.modremappingapi.impl.DefaultRemapLibrary; +import org.jetbrains.annotations.Nullable; + +import java.nio.file.Path; +import java.util.List; + +public interface RemapLibrary { + @Nullable String getURL(); + @Nullable Path getPath(); + String getFileName(); + List getToExclude(); + + static RemapLibrary of(Path path, String fileName) { + return new DefaultRemapLibrary(path, fileName); + } + + static RemapLibrary of(Path path, String fileName, List toExclude) { + return new DefaultRemapLibrary(path, fileName, toExclude); + } + + static RemapLibrary of(String url, String fileName, List toExclude) { + return new DefaultRemapLibrary(url, fileName, toExclude); + } +} diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultRemapLibrary.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultRemapLibrary.java new file mode 100644 index 0000000..55a2e4c --- /dev/null +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultRemapLibrary.java @@ -0,0 +1,54 @@ +package io.github.fabriccompatibilitylayers.modremappingapi.impl; + +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.RemapLibrary; +import org.jetbrains.annotations.Nullable; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class DefaultRemapLibrary implements RemapLibrary { + private final @Nullable String url; + private final @Nullable Path path; + private final String fileName; + private final List toExclude; + + public DefaultRemapLibrary(@Nullable String url, String fileName, List toExclude) { + this.url = url; + this.path = null; + this.fileName = fileName; + this.toExclude = toExclude; + } + + public DefaultRemapLibrary(@Nullable Path path, String fileName, List toExclude) { + this.url = null; + this.path = path; + this.fileName = fileName; + this.toExclude = toExclude; + } + + public DefaultRemapLibrary(@Nullable Path path, String fileName) { + this(path, fileName, Collections.emptyList()); + } + + @Override + public @Nullable String getURL() { + return this.url; + } + + @Override + public @Nullable Path getPath() { + return this.path; + } + + @Override + public String getFileName() { + return this.fileName; + } + + @Override + public List getToExclude() { + return this.toExclude; + } +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/RemapLibrary.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/RemapLibrary.java index c0472fa..3f4e6c4 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/RemapLibrary.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/RemapLibrary.java @@ -1,12 +1,13 @@ package io.github.fabriccompatibiltylayers.modremappingapi.api.v1; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; -public class RemapLibrary { +public class RemapLibrary implements io.github.fabriccompatibilitylayers.modremappingapi.api.v2.RemapLibrary { public final String url; public final Path path; public final List toExclude; @@ -40,4 +41,24 @@ public RemapLibrary(String url, Path path, List toExclude, String fileNa this.toExclude = toExclude; this.fileName = fileName; } + + @Override + public @Nullable String getURL() { + return this.url; + } + + @Override + public @Nullable Path getPath() { + return this.path; + } + + @Override + public String getFileName() { + return this.fileName; + } + + @Override + public List getToExclude() { + return this.toExclude; + } } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/LibraryHandler.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/LibraryHandler.java index feb3b6a..0644188 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/LibraryHandler.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/LibraryHandler.java @@ -1,33 +1,31 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl; import fr.catcore.modremapperapi.utils.Constants; -import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ModRemapper; -import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.RemapLibrary; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.CacheUtils; +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.CacheHandler; +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.RemapLibrary; import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils; -import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.tinyremapper.TinyRemapper; import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; public class LibraryHandler { - private final Map remapLibraries = new HashMap<>(); + private Map remapLibraries = new HashMap<>(); private String sourceNamespace; + private CacheHandler cacheHandler; public LibraryHandler() {} - public void init(String sourceNamespace) { + public void init(String sourceNamespace, CacheHandler cacheHandler) { this.sourceNamespace = sourceNamespace; + this.cacheHandler = cacheHandler; - Path sourceLibraryPath = CacheUtils.getLibraryPath(this.sourceNamespace); + Path sourceLibraryPath = this.cacheHandler.resolveLibrary(this.sourceNamespace); if (!Files.exists(sourceLibraryPath)) { try { @@ -38,34 +36,32 @@ public void init(String sourceNamespace) { } } - public void gatherRemapLibraries(List remappers) { - try { - for (ModRemapper remapper : remappers) { - List libraries = new ArrayList<>(); - - remapper.addRemapLibraries(libraries, FabricLoader.getInstance().getEnvironmentType()); - - Map temp = CacheUtils.computeExtraLibraryPaths(libraries, sourceNamespace); - - for (Map.Entry entry : temp.entrySet()) { - RemapLibrary library = entry.getKey(); - Path path = entry.getValue(); + private Map computeExtraLibraryPaths(Collection sourcePaths, String target) { + return sourcePaths.stream() + .collect(Collectors.toMap(p -> p, + p -> this.cacheHandler.resolveLibrary(target).resolve(p.getFileName()))); + } - if (Files.exists(path)) continue; + public void cacheLibraries(List libraries) { + remapLibraries = computeExtraLibraryPaths(libraries, sourceNamespace); - if (!library.url.isEmpty()) { - Constants.MAIN_LOGGER.info("Downloading remapping library '" + library.fileName + "' from url '" + library.url + "'"); - FileUtils.downloadFile(library.url, path); - FileUtils.removeEntriesFromZip(path, library.toExclude); - Constants.MAIN_LOGGER.info("Remapping library ready for use."); - } else if (library.path != null) { - Constants.MAIN_LOGGER.info("Extracting remapping library '" + library.fileName + "' from mod jar."); - FileUtils.copyZipFile(library.path, path); - Constants.MAIN_LOGGER.info("Remapping library ready for use."); - } + try { + for (Map.Entry entry : remapLibraries.entrySet()) { + RemapLibrary library = entry.getKey(); + Path path = entry.getValue(); + + if (Files.exists(path)) continue; + + if (library.getURL() != null && !library.getURL().isEmpty()) { + Constants.MAIN_LOGGER.info("Downloading remapping library '" + library.getFileName() + "' from url '" + library.getURL() + "'"); + FileUtils.downloadFile(library.getURL(), path); + FileUtils.removeEntriesFromZip(path, library.getToExclude()); + Constants.MAIN_LOGGER.info("Remapping library ready for use."); + } else if (library.getPath() != null) { + Constants.MAIN_LOGGER.info("Extracting remapping library '" + library.getFileName() + "' from mod jar."); + FileUtils.copyZipFile(library.getPath(), path); + Constants.MAIN_LOGGER.info("Remapping library ready for use."); } - - remapLibraries.putAll(temp); } } catch (IOException | URISyntaxException e) { throw new RuntimeException(e); diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModRemappingAPIImpl.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModRemappingAPIImpl.java index 2af1ecf..bd2e387 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModRemappingAPIImpl.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModRemappingAPIImpl.java @@ -61,6 +61,8 @@ public static void init() { context.afterRemap(); } + v2Remappers.values().forEach(l -> l.forEach(ModRemapper::afterAllRemappings)); + initializing = false; init = true; } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/ModRemapperContext.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/ModRemapperContext.java index 53258a1..6608a9b 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/ModRemapperContext.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/ModRemapperContext.java @@ -1,5 +1,6 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl.context; +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.CacheHandler; import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModCandidate; import io.github.fabriccompatibiltylayers.modremappingapi.impl.LibraryHandler; import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; @@ -23,4 +24,6 @@ public interface ModRemapperContext { LibraryHandler getLibraryHandler(); String getId(); MixinData getMixinData(); + void gatherLibraries(); + CacheHandler getCacheHandler(); } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java index bf778a0..4d38a7c 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java @@ -1,12 +1,14 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl.context.v1; import fr.catcore.modremapperapi.utils.Constants; +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.CacheHandler; import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModCandidate; import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModDiscovererConfig; import io.github.fabriccompatibilitylayers.modremappingapi.impl.DefaultModCandidate; import io.github.fabriccompatibilitylayers.modremappingapi.impl.InternalCacheHandler; import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingBuilder; import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.ModRemapper; +import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.RemapLibrary; import io.github.fabriccompatibiltylayers.modremappingapi.impl.*; import io.github.fabriccompatibiltylayers.modremappingapi.impl.compatibility.V0ModRemapper; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.BaseModRemapperContext; @@ -78,9 +80,7 @@ public void init() { throw new RuntimeException(e); } - libraryHandler.init(this.mappingsRegistry.getSourceNamespace()); - - libraryHandler.gatherRemapLibraries(remappers); + this.gatherLibraries(); this.registerAdditionalMappings(); this.mappingsRegistry.generateAdditionalMappings(); @@ -266,4 +266,22 @@ public LibraryHandler getLibraryHandler() { public MixinData getMixinData() { return mixinData; } + + @Override + public void gatherLibraries() { + libraryHandler.init(this.mappingsRegistry.getSourceNamespace(), this.cacheHandler); + + List libraries = new ArrayList<>(); + + for (ModRemapper remapper : remappers) { + remapper.addRemapLibraries(libraries, FabricLoader.getInstance().getEnvironmentType()); + } + + libraryHandler.cacheLibraries(new ArrayList<>(libraries)); + } + + @Override + public CacheHandler getCacheHandler() { + return this.cacheHandler; + } } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/V1CacheHandler.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/V1CacheHandler.java index a216d4f..87dcc44 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/V1CacheHandler.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/V1CacheHandler.java @@ -10,7 +10,7 @@ public class V1CacheHandler implements InternalCacheHandler { private final Path contextDirectory = CacheUtils.MAIN_FOLDER; private final Path tempDirectory = contextDirectory.resolve("temp"); - private final Path libsDirectory = contextDirectory.resolve("libs"); + private final Path libsDirectory = CacheUtils.LIBRARY_FOLDER; public V1CacheHandler() { for (Path p : new Path[] {tempDirectory, libsDirectory}) { diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java index 5abd98d..af27e74 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java @@ -11,6 +11,7 @@ import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.ModTrRemapper; import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.SoftLockFixer; import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.CacheUtils; +import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.tinyremapper.TinyRemapper; import java.io.ByteArrayInputStream; @@ -63,7 +64,7 @@ public void init() { throw new RuntimeException(e); } - libraryHandler.init(this.mappingsRegistry.getSourceNamespace()); + this.gatherLibraries(); this.mappingsRegistry.generateAdditionalMappings(); } @@ -162,4 +163,22 @@ public List getRemappers() { public MixinData getMixinData() { return mixinData; } + + @Override + public void gatherLibraries() { + libraryHandler.init(this.mappingsRegistry.getSourceNamespace(), this.cacheHandler); + + List libraries = new ArrayList<>(); + + for (ModRemapper remapper : remappers) { + remapper.addRemappingLibraries(libraries, FabricLoader.getInstance().getEnvironmentType()); + } + + libraryHandler.cacheLibraries(libraries); + } + + @Override + public CacheHandler getCacheHandler() { + return this.cacheHandler; + } } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/ModTrRemapper.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/ModTrRemapper.java index 06c1b94..c5d2687 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/ModTrRemapper.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/ModTrRemapper.java @@ -69,7 +69,7 @@ public static TinyRemapper makeRemapper(ModRemapperContext context) { TinyRemapper remapper = builder.build(); try { - MinecraftRemapper.addMinecraftJar(remapper, mappingsRegistry); + MinecraftRemapper.addMinecraftJar(remapper, mappingsRegistry, context.getCacheHandler()); } catch (IOException e) { throw new RuntimeException(e); } @@ -79,7 +79,7 @@ public static TinyRemapper makeRemapper(ModRemapperContext context) { return remapper; } - public static void remapMods(TinyRemapper remapper, Map paths, ModRemapperContext context) { + public static void remapMods(TinyRemapper remapper, Map paths, ModRemapperContext context) { List outputConsumerPaths = new ArrayList<>(); if (context.getRemappingFlags().contains(RemappingFlags.MIXIN)) { @@ -107,7 +107,7 @@ public static void remapMods(TinyRemapper remapper, Map entry : paths.entrySet()) { + for (Map.Entry entry : paths.entrySet()) { ModCandidate candidate = entry.getKey(); Path jarPath = entry.getValue(); @@ -123,13 +123,13 @@ public static void remapMods(TinyRemapper remapper, Map getRemapperConsumer(Map paths, ModRemapperContext context) { + private static @Nullable Consumer getRemapperConsumer(Map paths, ModRemapperContext context) { Consumer consumer = null; if (context.getRemappingFlags().contains(RemappingFlags.ACCESS_WIDENER)) { consumer = (currentRemapper) -> { - for (Map.Entry entry : paths.entrySet()) { - io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModCandidate candidate = entry.getKey(); + for (Map.Entry entry : paths.entrySet()) { + ModCandidate candidate = entry.getKey(); if (candidate.getAccessWidenerPath() != null) { try (FileSystem jarFs = FileUtils.getJarFileSystem(candidate.getPath())) { diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/minecraft/MinecraftRemapper.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/minecraft/MinecraftRemapper.java index 2601d85..f51dbab 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/minecraft/MinecraftRemapper.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/minecraft/MinecraftRemapper.java @@ -1,11 +1,11 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.minecraft; import fr.catcore.modremapperapi.utils.Constants; +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.CacheHandler; import io.github.fabriccompatibiltylayers.modremappingapi.impl.RemapUtils; import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingTreeHelper; import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.TrRemapperHelper; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.CacheUtils; import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.tinyremapper.NonClassCopyMode; @@ -17,17 +17,23 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.*; +import java.util.stream.Collectors; @ApiStatus.Internal public class MinecraftRemapper { - private static Collection getMinecraftJar(Collection sourcePaths, String src, String target, MappingsRegistry mappingsRegistry) throws IOException { - Path targetFolder = CacheUtils.getLibraryPath(target); + private static Map computeLibraryPaths(Collection sourcePaths, Path basePath) { + return sourcePaths.stream().collect(Collectors.toMap(p -> p, + p -> basePath.resolve(p.getFileName()))); + } + + private static Collection getMinecraftJar(Collection sourcePaths, String src, String target, MappingsRegistry mappingsRegistry, CacheHandler cacheHandler) throws IOException { + Path targetFolder = cacheHandler.resolveLibrary(target); if (!Files.exists(targetFolder)) { Files.createDirectories(targetFolder); } - Map paths = CacheUtils.computeLibraryPaths(new HashSet<>(sourcePaths), target); + Map paths = computeLibraryPaths(new HashSet<>(sourcePaths), targetFolder); if (FileUtils.exist(paths.values())) return paths.values(); @@ -62,20 +68,21 @@ private static Collection getMinecraftJar(Collection sourcePaths, St } @ApiStatus.Internal - public static void addMinecraftJar(TinyRemapper remapper, MappingsRegistry mappingsRegistry) throws IOException { + public static void addMinecraftJar(TinyRemapper remapper, MappingsRegistry mappingsRegistry, CacheHandler cacheHandler) throws IOException { Collection classPath; if (FabricLoader.getInstance().isDevelopmentEnvironment()) { try { classPath = getMinecraftJar( - getMinecraftJar(RemapUtils.getRemapClasspath(), mappingsRegistry.getTargetNamespace(), "intermediary", mappingsRegistry), + getMinecraftJar(RemapUtils.getRemapClasspath(), mappingsRegistry.getTargetNamespace(), "intermediary", mappingsRegistry, cacheHandler), "intermediary", "official", - mappingsRegistry + mappingsRegistry, + cacheHandler ); if (!mappingsRegistry.isSourceNamespaceObf()) { - classPath = getMinecraftJar(classPath, "official", mappingsRegistry.getSourceNamespace(), mappingsRegistry); + classPath = getMinecraftJar(classPath, "official", mappingsRegistry.getSourceNamespace(), mappingsRegistry, cacheHandler); } } catch (IOException e) { throw new RuntimeException("Failed to populate default remap classpath", e); @@ -84,7 +91,7 @@ public static void addMinecraftJar(TinyRemapper remapper, MappingsRegistry mappi classPath = RemapUtils.getClassPathFromObjectShare(); if (!mappingsRegistry.isSourceNamespaceObf()) { - classPath = getMinecraftJar(classPath, "official", mappingsRegistry.getSourceNamespace(), mappingsRegistry); + classPath = getMinecraftJar(classPath, "official", mappingsRegistry.getSourceNamespace(), mappingsRegistry, cacheHandler); } } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/CacheUtils.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/CacheUtils.java index f80cd60..082a9eb 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/CacheUtils.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/utils/CacheUtils.java @@ -1,14 +1,9 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl.utils; -import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.RemapLibrary; import net.fabricmc.loader.api.FabricLoader; import org.jetbrains.annotations.ApiStatus; -import java.nio.file.Files; import java.nio.file.Path; -import java.util.Collection; -import java.util.Map; -import java.util.stream.Collectors; @ApiStatus.Internal public class CacheUtils { @@ -16,29 +11,12 @@ public class CacheUtils { public static final Path MAIN_FOLDER = BASE_FOLDER .resolve(VersionHelper.MINECRAFT_VERSION) .resolve(VersionHelper.MOD_VERSION); - public static final Path LIBRARY_FOLDER = MAIN_FOLDER.resolve("libs"); + public static final Path LIBRARY_FOLDER = getCachePath("libs"); public static Path getCachePath(String pathName) { return MAIN_FOLDER.resolve(pathName); } - public static Path getLibraryPath(String pathName) { - return LIBRARY_FOLDER.resolve(pathName); - } - - @ApiStatus.Internal - public static Map computeLibraryPaths(Collection sourcePaths, String target) { - return sourcePaths.stream().collect(Collectors.toMap(p -> p, - p -> CacheUtils.getLibraryPath(target).resolve(p.getFileName()))); - } - - @ApiStatus.Internal - public static Map computeExtraLibraryPaths(Collection sourcePaths, String target) { - return sourcePaths.stream() - .collect(Collectors.toMap(p -> p, - p -> CacheUtils.getLibraryPath(target).resolve(p.fileName))); - } - static { BASE_FOLDER.toFile().mkdirs(); MAIN_FOLDER.toFile().mkdirs(); From 1a2ec4b4aa78bb943ea4867557d86dc860088ef9 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Wed, 9 Apr 2025 21:59:01 +0200 Subject: [PATCH 11/14] Port over remaining v1 api features to v2 api --- .../modremappingapi/api/v2/CacheHandler.java | 6 ++ .../api/v2/MappingBuilder.java | 14 +++ .../modremappingapi/api/v2/MappingUtils.java | 90 +++++++++++++++++++ .../api/v2/MappingsConfig.java | 1 + .../modremappingapi/api/v2/ModRemapper.java | 3 + .../modremappingapi/api/v2/VisitorInfos.java | 33 +++++++ .../modremappingapi/api/v1/MappingUtils.java | 14 ++- .../modremappingapi/api/v1/VisitorInfos.java | 12 ++- .../impl/MappingsUtilsImpl.java | 9 +- .../impl/VisitorInfosImpl.java | 26 ++++-- .../context/MappingsRegistryInstance.java | 6 +- .../impl/context/v1/ModRemapperV1Context.java | 2 +- .../v1/V1MappingBuilderImpl.java} | 6 +- .../impl/context/v2/ModRemmaperV2Context.java | 24 +++++ .../impl/context/v2/V2MappingBuilderImpl.java | 76 ++++++++++++++++ .../impl/remapper/asm/MRAMethodVisitor.java | 16 ++-- 16 files changed, 308 insertions(+), 30 deletions(-) create mode 100644 src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingBuilder.java create mode 100644 src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingUtils.java create mode 100644 src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/VisitorInfos.java rename src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/{MappingBuilderImpl.java => context/v1/V1MappingBuilderImpl.java} (92%) create mode 100644 src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2MappingBuilderImpl.java diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/CacheHandler.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/CacheHandler.java index b122e3c..52c2b6c 100644 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/CacheHandler.java +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/CacheHandler.java @@ -1,9 +1,15 @@ package io.github.fabriccompatibilitylayers.modremappingapi.api.v2; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.BaseModRemapperContext; + import java.nio.file.Path; public interface CacheHandler { Path resolveTemp(String name); Path resolveCache(String name); Path resolveLibrary(String name); + + static CacheHandler getCacheHandler(String contextId) { + return BaseModRemapperContext.get(contextId).getCacheHandler(); + } } diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingBuilder.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingBuilder.java new file mode 100644 index 0000000..3410f96 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingBuilder.java @@ -0,0 +1,14 @@ +package io.github.fabriccompatibilitylayers.modremappingapi.api.v2; + +public interface MappingBuilder { + + ClassMapping addMapping(String sourceName, String targetName); + ClassMapping addMapping(String name); + + public interface ClassMapping { + ClassMapping field(String sourceName, String targetName, String sourceDescriptor); + ClassMapping field(String name, String descriptor); + ClassMapping method(String sourceName, String targetName, String sourceDescriptor); + ClassMapping method(String name, String descriptor); + } +} diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingUtils.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingUtils.java new file mode 100644 index 0000000..1cb791c --- /dev/null +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingUtils.java @@ -0,0 +1,90 @@ +package io.github.fabriccompatibilitylayers.modremappingapi.api.v2; + +import io.github.fabriccompatibiltylayers.modremappingapi.impl.MappingsUtilsImpl; +import org.jetbrains.annotations.Nullable; + +public interface MappingUtils { + /** + * + * @param className original class name + * @return remapped class name + */ + static String mapClass(String contextId, String className) { + return MappingsUtilsImpl.mapClass(MappingsUtilsImpl.getMappingsRegistry(contextId), className); + } + + /** + * + * @param className remapped class name + * @return original class name + */ + static String unmapClass(String contextId, String className) { + return MappingsUtilsImpl.unmapClass(MappingsUtilsImpl.getMappingsRegistry(contextId), className); + } + + /** + * + * @param className original class name + * @param fieldName + * @param fieldDesc + * @return + */ + static ClassMember mapField(String contextId, String className, String fieldName, @Nullable String fieldDesc) { + return MappingsUtilsImpl.mapField(MappingsUtilsImpl.getMappingsRegistry(contextId), className, fieldName, fieldDesc); + } + + /** + * + * @param className remapped class name + * @param fieldName + * @param fieldDesc + * @return + */ + static ClassMember mapFieldFromRemappedClass(String contextId, String className, String fieldName, @Nullable String fieldDesc) { + return MappingsUtilsImpl.mapFieldFromRemappedClass(MappingsUtilsImpl.getMappingsRegistry(contextId), className, fieldName, fieldDesc); + } + + /** + * + * @param className original class name + * @param methodName + * @param methodDesc + * @return + */ + static ClassMember mapMethod(String contextId, String className, String methodName, String methodDesc) { + return MappingsUtilsImpl.mapMethod(MappingsUtilsImpl.getMappingsRegistry(contextId), className, methodName, methodDesc); + } + + /** + * + * @param className remapped class name + * @param methodName + * @param methodDesc + * @return + */ + static ClassMember mapMethodFromRemappedClass(String contextId, String className, String methodName, String methodDesc) { + return MappingsUtilsImpl.mapMethodFromRemappedClass(MappingsUtilsImpl.getMappingsRegistry(contextId), className, methodName, methodDesc); + } + + static ClassMember mapField(String contextId, Class owner, String fieldName) { + return MappingsUtilsImpl.mapField(MappingsUtilsImpl.getMappingsRegistry(contextId), owner, fieldName); + } + + static ClassMember mapMethod(String contextId, Class owner, String methodName, Class[] parameterTypes) { + return MappingsUtilsImpl.mapMethod(MappingsUtilsImpl.getMappingsRegistry(contextId), owner, methodName, parameterTypes); + } + + /** + * + * @param desc original descriptor + * @return remapped descriptor + */ + static String mapDescriptor(String contextId, String desc) { + return MappingsUtilsImpl.mapDescriptor(MappingsUtilsImpl.getMappingsRegistry(contextId), desc); + } + + interface ClassMember { + String getName(); + @Nullable String getDesc(); + } +} diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingsConfig.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingsConfig.java index 023b38e..08c3f5e 100644 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingsConfig.java +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingsConfig.java @@ -10,6 +10,7 @@ public interface MappingsConfig { @Nullable String getSourceNamespace(); @Nullable Supplier getExtraMappings(); Map getRenamingMap(); + @Nullable String getDefaultPackage(); static MappingsConfig defaultConfig() { return new DefaultMappingsConfig(); diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java index 4f76b58..468bac7 100644 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/ModRemapper.java @@ -17,4 +17,7 @@ public interface ModRemapper { void afterAllRemappings(); void addRemappingLibraries(List libraries, EnvType environment); + void registerAdditionalMappings(MappingBuilder mappingBuilder); + void registerPreVisitors(VisitorInfos visitorInfos); + void registerPostVisitors(VisitorInfos visitorInfos); } diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/VisitorInfos.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/VisitorInfos.java new file mode 100644 index 0000000..d416b33 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/VisitorInfos.java @@ -0,0 +1,33 @@ +package io.github.fabriccompatibilitylayers.modremappingapi.api.v2; + +import org.jetbrains.annotations.Nullable; + +public interface VisitorInfos { + void registerSuperType(String target, String replacement); + + void registerTypeAnnotation(String target, String replacement); + + void registerMethodTypeIns(String target, String replacement); + + void registerFieldRef(String targetClass, String targetField, String targetDesc, FullClassMember classMember); + + void registerMethodInvocation(String targetClass, String targetMethod, String targetDesc, FullClassMember classMember); + + void registerLdc(String targetClass, Object targetLdc, Object replacement); + + void registerInstantiation(String target, String replacement); + + + static FullClassMember classMember(String owner, String name, @Nullable String desc, @Nullable Boolean isStatic) { + return new io.github.fabriccompatibiltylayers.modremappingapi.api.v1.VisitorInfos.FullClassMember(owner, name, desc, isStatic); + } + + static FullClassMember classMember(String owner, String name, @Nullable Boolean isStatic) { + return new io.github.fabriccompatibiltylayers.modremappingapi.api.v1.VisitorInfos.FullClassMember(owner, name, isStatic); + } + + interface FullClassMember extends MappingUtils.ClassMember { + String getOwner(); + @Nullable Boolean isStatic(); + } +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/MappingUtils.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/MappingUtils.java index 179df43..0e62a36 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/MappingUtils.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/MappingUtils.java @@ -84,15 +84,23 @@ static String mapDescriptor(String desc) { return MappingsUtilsImpl.mapDescriptor(MappingsUtilsImpl.getV1Registry(), desc); } - class ClassMember { + class ClassMember implements io.github.fabriccompatibilitylayers.modremappingapi.api.v2.MappingUtils.ClassMember { public final @NotNull String name; public final @Nullable String desc; public ClassMember(@NotNull String name, @Nullable String desc) { - assert name != null; - this.name = name; this.desc = desc; } + + @Override + public @NotNull String getName() { + return this.name; + } + + @Override + public @Nullable String getDesc() { + return this.desc; + } } } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/VisitorInfos.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/VisitorInfos.java index 4225d95..42f883c 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/VisitorInfos.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/VisitorInfos.java @@ -18,7 +18,7 @@ public interface VisitorInfos { void registerInstantiation(String target, String replacement); - class FullClassMember extends MappingUtils.ClassMember { + class FullClassMember extends MappingUtils.ClassMember implements io.github.fabriccompatibilitylayers.modremappingapi.api.v2.VisitorInfos.FullClassMember { public final String owner; public final @Nullable Boolean isStatic; @@ -31,5 +31,15 @@ public FullClassMember(String owner, String name, @Nullable String desc, @Nullab public FullClassMember(String owner, String name, @Nullable Boolean isStatic) { this(owner, name, null, isStatic); } + + @Override + public String getOwner() { + return this.owner; + } + + @Override + public @Nullable Boolean isStatic() { + return this.isStatic; + } } } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/MappingsUtilsImpl.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/MappingsUtilsImpl.java index 8f89c4e..0b51bc8 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/MappingsUtilsImpl.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/MappingsUtilsImpl.java @@ -1,6 +1,7 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl; import io.github.fabriccompatibiltylayers.modremappingapi.api.MappingUtils; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.BaseModRemapperContext; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.v1.ModRemapperV1Context; import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; import net.fabricmc.api.EnvType; @@ -31,6 +32,10 @@ public static MappingsRegistry getV1Registry() { return ModRemapperV1Context.INSTANCE.getMappingsRegistry(); } + public static MappingsRegistry getMappingsRegistry(String contextId) { + return BaseModRemapperContext.get(contextId).getMappingsRegistry(); + } + public static String mapClass(MappingsRegistry registry, String className) { int srcNamespace = registry.getFullMappings().getNamespaceId(registry.getSourceNamespace()); int targetNamespace = registry.getFullMappings().getNamespaceId(registry.getTargetNamespace()); @@ -151,11 +156,11 @@ public static MappingUtils.ClassMember mapMethod(MappingsRegistry registry, Clas String methodSubName = methodDef.getName(srcNamespace); if (Objects.equals(methodSubName, methodName)) { - String methodDescriptor = methodDef.getDesc(registry.getTargetNamespace()); + String methodDescriptor = methodDef.getDesc(targetNamespace); if (methodDescriptor != null && methodDescriptor.startsWith(argDesc)) { return new MappingUtils.ClassMember( - methodDef.getName(registry.getTargetNamespace()), + methodDef.getName(targetNamespace), methodDescriptor ); } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/VisitorInfosImpl.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/VisitorInfosImpl.java index db2c14d..48253bd 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/VisitorInfosImpl.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/VisitorInfosImpl.java @@ -1,20 +1,20 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl; -import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.VisitorInfos; +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.VisitorInfos; import org.jetbrains.annotations.ApiStatus; import java.util.HashMap; import java.util.Map; @ApiStatus.Internal -public class VisitorInfosImpl extends fr.catcore.modremapperapi.remapping.VisitorInfos implements VisitorInfos { +public class VisitorInfosImpl extends fr.catcore.modremapperapi.remapping.VisitorInfos implements VisitorInfos, io.github.fabriccompatibiltylayers.modremappingapi.api.v1.VisitorInfos { public final Map SUPERS = new HashMap<>(); public final Map ANNOTATION = new HashMap<>(); public final Map METHOD_TYPE = new HashMap<>(); public final Map INSTANTIATION = new HashMap<>(); - public final Map>> METHOD_INVOCATION = new HashMap<>(); - public final Map>> FIELD_REF = new HashMap<>(); + public final Map>> METHOD_INVOCATION = new HashMap<>(); + public final Map>> FIELD_REF = new HashMap<>(); public final Map> LDC = new HashMap<>(); @Override @@ -33,14 +33,24 @@ public void registerMethodTypeIns(String target, String replacement) { } @Override - public void registerFieldRef(String targetClass, String targetField, String targetDesc, FullClassMember classMember) { + public void registerFieldRef(String targetClass, String targetField, String targetDesc, io.github.fabriccompatibiltylayers.modremappingapi.api.v1.VisitorInfos.FullClassMember classMember) { + this.registerFieldRef(targetClass, targetField, targetDesc, (VisitorInfos.FullClassMember) classMember); + } + + @Override + public void registerMethodInvocation(String targetClass, String targetMethod, String targetDesc, io.github.fabriccompatibiltylayers.modremappingapi.api.v1.VisitorInfos.FullClassMember classMember) { + this.registerMethodInvocation(targetClass, targetMethod, targetDesc, (VisitorInfos.FullClassMember) classMember); + } + + @Override + public void registerFieldRef(String targetClass, String targetField, String targetDesc, VisitorInfos.FullClassMember classMember) { FIELD_REF.computeIfAbsent(targetClass, k -> new HashMap<>()) .computeIfAbsent(targetField, k -> new HashMap<>()) .put(targetDesc, classMember); } @Override - public void registerMethodInvocation(String targetClass, String targetMethod, String targetDesc, FullClassMember classMember) { + public void registerMethodInvocation(String targetClass, String targetMethod, String targetDesc, VisitorInfos.FullClassMember classMember) { METHOD_INVOCATION.computeIfAbsent(targetClass, k -> new HashMap<>()) .computeIfAbsent(targetMethod, k -> new HashMap<>()) .put(targetDesc, classMember); @@ -89,14 +99,14 @@ public void registerMethodLdcIns(MethodValue target, MethodValue replacement) { .put(target.value, replacement.value); } - private void registerMethodNamed(MethodNamed target, MethodNamed replacementObject, Map>> map) { + private void registerMethodNamed(MethodNamed target, MethodNamed replacementObject, Map>> map) { String targetClass = target.owner; String targetMember = target.name; String replacement = replacementObject.name; if (replacement == null) replacement = ""; - FullClassMember classMember = new FullClassMember(replacementObject.owner, replacement, null, null); + VisitorInfos.FullClassMember classMember = new io.github.fabriccompatibiltylayers.modremappingapi.api.v1.VisitorInfos.FullClassMember(replacementObject.owner, replacement, null, null); if (targetMember == null) targetMember = ""; diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MappingsRegistryInstance.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MappingsRegistryInstance.java index 63d883f..b56dcb7 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MappingsRegistryInstance.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MappingsRegistryInstance.java @@ -1,11 +1,9 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl.context; -import fr.catcore.modremapperapi.utils.Constants; import fr.catcore.wfvaio.WhichFabricVariantAmIOn; import io.github.fabriccompatibilitylayers.modremappingapi.impl.InternalCacheHandler; import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingBuilder; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.MappingBuilderImpl; -import io.github.fabriccompatibiltylayers.modremappingapi.impl.MappingsUtilsImpl; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.v1.V1MappingBuilderImpl; import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingTreeHelper; import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils; @@ -137,7 +135,7 @@ public void setDefaultPackage(String defaultPackage) { @Override public void addModMappings(Path path) { - MappingBuilder mappingBuilder = new MappingBuilderImpl(mods); + MappingBuilder mappingBuilder = new V1MappingBuilderImpl(mods); try { FileUtils.listPathContent(path) diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java index 4d38a7c..f9c9f77 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java @@ -231,7 +231,7 @@ public MappingsRegistry getMappingsRegistry() { } private void registerAdditionalMappings() { - MappingBuilder builder = new MappingBuilderImpl(mappingsRegistry.getAdditionalMappings()); + MappingBuilder builder = new V1MappingBuilderImpl(mappingsRegistry.getAdditionalMappings()); for (ModRemapper remapper : remappers) { remapper.registerMappings(builder); diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/MappingBuilderImpl.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/V1MappingBuilderImpl.java similarity index 92% rename from src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/MappingBuilderImpl.java rename to src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/V1MappingBuilderImpl.java index 1222533..d22c996 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/MappingBuilderImpl.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/V1MappingBuilderImpl.java @@ -1,4 +1,4 @@ -package io.github.fabriccompatibiltylayers.modremappingapi.impl; +package io.github.fabriccompatibiltylayers.modremappingapi.impl.context.v1; import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.MappingBuilder; import net.fabricmc.mappingio.MappedElementKind; @@ -7,10 +7,10 @@ import org.jetbrains.annotations.Nullable; @ApiStatus.Internal -public class MappingBuilderImpl implements MappingBuilder { +public class V1MappingBuilderImpl implements MappingBuilder { private final MemoryMappingTree next; - public MappingBuilderImpl(MemoryMappingTree next) { + public V1MappingBuilderImpl(MemoryMappingTree next) { this.next = next; } diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java index af27e74..08e38d1 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java @@ -4,12 +4,14 @@ import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.*; import io.github.fabriccompatibilitylayers.modremappingapi.impl.InternalCacheHandler; import io.github.fabriccompatibiltylayers.modremappingapi.impl.LibraryHandler; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.VisitorInfosImpl; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.BaseModRemapperContext; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.MappingsRegistryInstance; import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.MixinData; import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry; import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.ModTrRemapper; import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.SoftLockFixer; +import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor.MRAApplyVisitor; import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.CacheUtils; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.tinyremapper.TinyRemapper; @@ -55,6 +57,10 @@ public void init() { } } + if (mappings.getDefaultPackage() != null) { + this.mappingsRegistry.setDefaultPackage(mappings.getDefaultPackage()); + } + remapFlags.addAll(remapper.getRemappingFlags()); } @@ -66,6 +72,7 @@ public void init() { this.gatherLibraries(); + this.registerAdditionalMappings(); this.mappingsRegistry.generateAdditionalMappings(); } @@ -140,9 +147,26 @@ public MappingsRegistry getMappingsRegistry() { return mappingsRegistry; } + private void registerAdditionalMappings() { + MappingBuilder builder = new V2MappingBuilderImpl(mappingsRegistry.getAdditionalMappings()); + + for (ModRemapper remapper : remappers) { + remapper.registerAdditionalMappings(builder); + } + } + @Override public void addToRemapperBuilder(TinyRemapper.Builder builder) { + VisitorInfosImpl preInfos = new VisitorInfosImpl(); + VisitorInfosImpl postInfos = new VisitorInfosImpl(); + + for (ModRemapper remapper : remappers) { + remapper.registerPreVisitors(preInfos); + remapper.registerPostVisitors(postInfos); + } + builder.extraPreApplyVisitor(new MRAApplyVisitor(preInfos)); + builder.extraPostApplyVisitor(new MRAApplyVisitor(postInfos)); } @Override diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2MappingBuilderImpl.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2MappingBuilderImpl.java new file mode 100644 index 0000000..171a886 --- /dev/null +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/V2MappingBuilderImpl.java @@ -0,0 +1,76 @@ +package io.github.fabriccompatibiltylayers.modremappingapi.impl.context.v2; + +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.MappingBuilder; +import net.fabricmc.mappingio.MappedElementKind; +import net.fabricmc.mappingio.tree.MemoryMappingTree; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +@ApiStatus.Internal +public class V2MappingBuilderImpl implements MappingBuilder { + private final MemoryMappingTree next; + + public V2MappingBuilderImpl(MemoryMappingTree next) { + this.next = next; + } + + @Override + public ClassMapping addMapping(String sourceName, String targetName) { + this.next.visitClass(sourceName); + this.next.visitDstName(MappedElementKind.CLASS, 0, targetName); + return new ClassMappingImpl(sourceName, targetName, next); + } + + @Override + public ClassMapping addMapping(String name) { + this.next.visitClass(name); + return new ClassMappingImpl(name, null, next); + } + + private static class ClassMappingImpl implements ClassMapping { + private final String sourceName; + private final @Nullable String targetName; + private final MemoryMappingTree next; + + public ClassMappingImpl(String sourceName, @Nullable String targetName, MemoryMappingTree next) { + this.sourceName = sourceName; + this.targetName = targetName; + this.next = next; + } + + private void visit() { + this.next.visitClass(sourceName); + if (targetName != null) this.next.visitDstName(MappedElementKind.CLASS, 0, targetName); + } + + @Override + public ClassMapping field(String sourceName, String targetName, String sourceDescriptor) { + visit(); + + this.next.visitField(sourceName, sourceDescriptor); + if (targetName != null) this.next.visitDstName(MappedElementKind.FIELD, 0, targetName); + + return this; + } + + @Override + public ClassMapping field(String name, String descriptor) { + return this.field(name, null, descriptor); + } + + @Override + public ClassMapping method(String sourceName, String targetName, String sourceDescriptor) { + visit(); + + this.next.visitMethod(sourceName, sourceDescriptor); + if (targetName != null) this.next.visitDstName(MappedElementKind.METHOD, 0, targetName); + + return this; + } + + @Override + public ClassMapping method(String name, String descriptor) { + return this.method(name, null, descriptor); + } + } +} diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/asm/MRAMethodVisitor.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/asm/MRAMethodVisitor.java index 1a9600a..f2fcde9 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/asm/MRAMethodVisitor.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/asm/MRAMethodVisitor.java @@ -1,6 +1,6 @@ package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.asm; -import io.github.fabriccompatibiltylayers.modremappingapi.api.v1.VisitorInfos; +import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.VisitorInfos; import io.github.fabriccompatibiltylayers.modremappingapi.impl.VisitorInfosImpl; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; @@ -57,9 +57,9 @@ public void visitFieldInsn(int opcode, String owner, String name, String descrip } if (classMember != null) { - currentOwner = classMember.owner; - currentName = classMember.name; - currentDescriptor = classMember.desc; + currentOwner = classMember.getOwner(); + currentName = classMember.getName(); + currentDescriptor = classMember.getDesc(); } } } @@ -107,11 +107,11 @@ public void visitMethodInsn(int opcode, String owner, String name, String descri } if (fullClassMember != null) { - currentOwner = fullClassMember.owner; - currentName = fullClassMember.name; - currentDescriptor = fullClassMember.desc; + currentOwner = fullClassMember.getOwner(); + currentName = fullClassMember.getName(); + currentDescriptor = fullClassMember.getDesc(); - if (fullClassMember.isStatic != null) currentOpcode = fullClassMember.isStatic ? INVOKESTATIC : INVOKEVIRTUAL; + if (fullClassMember.isStatic() != null) currentOpcode = fullClassMember.isStatic() ? INVOKESTATIC : INVOKEVIRTUAL; } } } From 454d8fe519d139afe64eada0d2e4376ffd1bfb94 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Wed, 9 Apr 2025 22:03:34 +0200 Subject: [PATCH 12/14] Fix compiling errors --- .../modremappingapi/impl/DefaultMappingsConfig.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultMappingsConfig.java b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultMappingsConfig.java index 8b9412f..97f59ce 100644 --- a/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultMappingsConfig.java +++ b/src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultMappingsConfig.java @@ -1,6 +1,7 @@ package io.github.fabriccompatibilitylayers.modremappingapi.impl; import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.MappingsConfig; +import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.Map; @@ -21,4 +22,9 @@ public Supplier getExtraMappings() { public Map getRenamingMap() { return new HashMap<>(); } + + @Override + public @Nullable String getDefaultPackage() { + return null; + } } From e2b59c66336bb7401e17cc2e633abd2c1f1a0877 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Wed, 9 Apr 2025 22:22:57 +0200 Subject: [PATCH 13/14] Mark api v1 as deprecated --- .../modremappingapi/api/v1/MappingBuilder.java | 2 ++ .../modremappingapi/api/v1/MappingUtils.java | 4 ++++ .../modremappingapi/api/v1/ModRemapper.java | 5 +++++ .../modremappingapi/api/v1/RemapLibrary.java | 1 + .../modremappingapi/api/v1/VisitorInfos.java | 2 ++ 5 files changed, 14 insertions(+) diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/MappingBuilder.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/MappingBuilder.java index fb9e64a..8742693 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/MappingBuilder.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/MappingBuilder.java @@ -1,10 +1,12 @@ package io.github.fabriccompatibiltylayers.modremappingapi.api.v1; +@Deprecated public interface MappingBuilder { ClassMapping addMapping(String sourceName, String targetName); ClassMapping addMapping(String name); + @Deprecated public interface ClassMapping { ClassMapping field(String sourceName, String targetName, String sourceDescriptor); ClassMapping field(String name, String descriptor); diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/MappingUtils.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/MappingUtils.java index 0e62a36..c7a3774 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/MappingUtils.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/MappingUtils.java @@ -4,6 +4,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +/** + * @deprecated Use {@link io.github.fabriccompatibilitylayers.modremappingapi.api.v2.MappingUtils} instead. + */ +@Deprecated public interface MappingUtils { /** * diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/ModRemapper.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/ModRemapper.java index f114218..d84b454 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/ModRemapper.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/ModRemapper.java @@ -7,6 +7,11 @@ import java.util.Optional; import java.util.function.Supplier; +/** + * @deprecated Use {@link io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModRemapper} with entrypoint key "mod-remapper-api:modremapper_v2" + * instead. + */ +@Deprecated public interface ModRemapper { String[] getJarFolders(); diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/RemapLibrary.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/RemapLibrary.java index 3f4e6c4..2539ef1 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/RemapLibrary.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/RemapLibrary.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.List; +@Deprecated public class RemapLibrary implements io.github.fabriccompatibilitylayers.modremappingapi.api.v2.RemapLibrary { public final String url; public final Path path; diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/VisitorInfos.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/VisitorInfos.java index 42f883c..f96a303 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/VisitorInfos.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/api/v1/VisitorInfos.java @@ -3,6 +3,7 @@ import io.github.fabriccompatibiltylayers.modremappingapi.api.MappingUtils; import org.jetbrains.annotations.Nullable; +@Deprecated public interface VisitorInfos { void registerSuperType(String target, String replacement); @@ -18,6 +19,7 @@ public interface VisitorInfos { void registerInstantiation(String target, String replacement); + @Deprecated class FullClassMember extends MappingUtils.ClassMember implements io.github.fabriccompatibilitylayers.modremappingapi.api.v2.VisitorInfos.FullClassMember { public final String owner; public final @Nullable Boolean isStatic; From 508b6459b7658cda65d9dd6e27df9224543ce6b8 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Wed, 9 Apr 2025 22:35:31 +0200 Subject: [PATCH 14/14] Avoid overwriting the remapper list when adding new ones dynamically --- .../modremappingapi/impl/ModRemappingAPIImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModRemappingAPIImpl.java b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModRemappingAPIImpl.java index bd2e387..7fda287 100644 --- a/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModRemappingAPIImpl.java +++ b/src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/ModRemappingAPIImpl.java @@ -56,7 +56,8 @@ public static void init() { .stream().collect(Collectors.groupingBy(ModRemapper::getContextId)); v2Keys.addAll(newRemappers.keySet()); - v2Remappers.putAll(newRemappers); + + newRemappers.forEach((k, v) -> v2Remappers.computeIfAbsent(k, k2 -> new ArrayList<>()).addAll(v)); context.afterRemap(); }