diff --git a/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java b/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java index 48bcff52f..5958e8d7b 100644 --- a/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java @@ -279,7 +279,7 @@ private void remapJars(List remapList) throws IOException { if (extension.isForgeLike()) { AtRemapper.remap(project, output, mappings); - CoreModClassRemapper.remapJar(project, output, mappings); + CoreModClassRemapper.remapJar(project, extension.getPlatform().get(), output, mappings); } dependency.copyToCache(project, output, null); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java index 7aae63764..8f59433c6 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java @@ -443,7 +443,7 @@ private void remapCoreMods(Path patchedJar, SharedServiceManager serviceManager) final MappingOption mappingOption = MappingOption.forPlatform(getExtension()); final TinyMappingsService mappingsService = getExtension().getMappingConfiguration().getMappingsService(serviceManager, mappingOption); final MappingTree mappings = mappingsService.getMappingTree(); - CoreModClassRemapper.remapJar(project, patchedJar, mappings); + CoreModClassRemapper.remapJar(project, getExtension().getPlatform().get(), patchedJar, mappings); } private void patchJars() throws Exception { diff --git a/src/main/java/net/fabricmc/loom/util/srg/CoreModClassRemapper.java b/src/main/java/net/fabricmc/loom/util/srg/CoreModClassRemapper.java index 275c42181..bb8f26a26 100644 --- a/src/main/java/net/fabricmc/loom/util/srg/CoreModClassRemapper.java +++ b/src/main/java/net/fabricmc/loom/util/srg/CoreModClassRemapper.java @@ -34,6 +34,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -45,6 +46,7 @@ import net.fabricmc.loom.build.IntermediaryNamespaces; import net.fabricmc.loom.util.FileSystemUtil; +import net.fabricmc.loom.util.ModPlatform; import net.fabricmc.loom.util.function.CollectionUtil; import net.fabricmc.mappingio.tree.MappingTree; @@ -55,8 +57,9 @@ */ public final class CoreModClassRemapper { private static final Pattern CLASS_NAME_PATTERN = Pattern.compile("^(.*')((?:com\\.mojang\\.|net\\.minecraft\\.)[A-Za-z0-9.-_$]+)('.*)$"); + private static final Pattern REDIRECT_FIELD_TO_METHOD_PATTERN = Pattern.compile("^(.*\\w+\\s*\\.\\s*redirectFieldToMethod\\s*\\(\\s*\\w+\\s*,\\s*')(\\w*)('\\s*,(?:\\s*'(\\w+)'\\s*|.*)\\).*)$"); - public static void remapJar(Project project, Path jar, MappingTree mappings) throws IOException { + public static void remapJar(Project project, ModPlatform platform, Path jar, MappingTree mappings) throws IOException { final Logger logger = project.getLogger(); final String sourceNamespace = IntermediaryNamespaces.intermediary(project); @@ -80,7 +83,7 @@ public static void remapJar(Project project, Path jar, MappingTree mappings) thr if (Files.exists(js)) { logger.info(":remapping coremod '" + file + "'"); - remap(js, mappings, sourceNamespace); + remap(js, platform, mappings, sourceNamespace); } else { logger.warn("Coremod '" + file + "' listed in coremods.json but not found"); } @@ -88,9 +91,10 @@ public static void remapJar(Project project, Path jar, MappingTree mappings) thr } } - public static void remap(Path js, MappingTree mappings, String sourceNamespace) throws IOException { + public static void remap(Path js, ModPlatform platform, MappingTree mappings, String sourceNamespace) throws IOException { List lines = Files.readAllLines(js); List output = new ArrayList<>(lines); + String lastClassName = null; for (int i = 0; i < lines.size(); i++) { String line = lines.get(i); @@ -101,10 +105,36 @@ public static void remap(Path js, MappingTree mappings, String sourceNamespace) String remapped = CollectionUtil.find(mappings.getClasses(), def -> def.getName(sourceNamespace).equals(className)) .map(def -> def.getName("named")) .orElse(className); + lastClassName = remapped; if (!className.equals(remapped)) { output.set(i, matcher.group(1) + remapped.replace('/', '.') + matcher.group(3)); } + } else if (platform == ModPlatform.NEOFORGE && lastClassName != null) { + matcher = REDIRECT_FIELD_TO_METHOD_PATTERN.matcher(line); + + if (matcher.matches()) { + String fieldName = matcher.group(2); + String remapped = Optional.ofNullable(mappings.getClass(lastClassName, mappings.getNamespaceId("named"))) + .flatMap(clazz -> Optional.ofNullable(clazz.getField(fieldName, null, mappings.getNamespaceId(sourceNamespace)))) + .map(field -> field.getName("named")) + .orElse(fieldName); + + if (!fieldName.equals(remapped)) { + String optionalMethod = matcher.group(4); + String remappedMethod = optionalMethod == null ? null + : Optional.ofNullable(mappings.getClass(lastClassName, mappings.getNamespaceId("named"))) + .flatMap(clazz -> Optional.ofNullable(clazz.getMethod(optionalMethod, null, mappings.getNamespaceId(sourceNamespace)))) + .map(method -> method.getName("named")) + .orElse(null); + + if (remappedMethod != null) { + output.set(i, matcher.group(1) + remapped + matcher.group(3).replace("'" + optionalMethod + "'", "'" + remappedMethod + "'")); + } else { + output.set(i, matcher.group(1) + remapped + matcher.group(3)); + } + } + } } }