diff --git a/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java b/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java index c359485c..27c36f37 100644 --- a/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java +++ b/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java @@ -73,13 +73,13 @@ public class LoomRepositoryPlugin implements Plugin { repositories.ivy(repo -> { repo.setUrl(files.getUserCache()); - repo.patternLayout(layout -> layout.artifact("[revision]/[artifact]-[revision](-[classifier])(.[ext])")); + repo.patternLayout(layout -> layout.artifact("[revision]/[artifact](-[classifier])(.[ext])")); repo.metadataSources(IvyArtifactRepository.MetadataSources::artifact); }); repositories.ivy(repo -> { repo.setUrl(files.getRootProjectPersistentCache()); - repo.patternLayout(layout -> layout.artifact("[revision]/[artifact]-[revision](-[classifier])(.[ext])")); + repo.patternLayout(layout -> layout.artifact("[revision]/[artifact](-[classifier])(.[ext])")); repo.metadataSources(IvyArtifactRepository.MetadataSources::artifact); }); } diff --git a/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java b/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java index 83ebadff..c4f89d99 100644 --- a/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java +++ b/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java @@ -82,7 +82,7 @@ public abstract class AnnotationProcessorInvoker { LoomGradleExtension loom = LoomGradleExtension.get(project); String refmapName = Objects.requireNonNull(MixinApExtension.getMixinInformationContainer(sourceSet)).refmapNameProvider().get(); Map args = new HashMap<>() {{ - put(Constants.MixinArguments.IN_MAP_FILE_NAMED_INTERMEDIARY, loom.getMappingsProvider().tinyMappings.getCanonicalPath()); + put(Constants.MixinArguments.IN_MAP_FILE_NAMED_INTERMEDIARY, loom.getMappingsProvider().tinyMappings.toFile().getCanonicalPath()); put(Constants.MixinArguments.OUT_MAP_FILE_NAMED_INTERMEDIARY, loom.getNextMixinMappings().getCanonicalPath()); put(Constants.MixinArguments.OUT_REFMAP_FILE, getRefmapDestination(task, refmapName)); put(Constants.MixinArguments.DEFAULT_OBFUSCATION_ENV, "named:intermediary"); diff --git a/src/main/java/net/fabricmc/loom/configuration/DependencyProvider.java b/src/main/java/net/fabricmc/loom/configuration/DependencyProvider.java index 9a123adc..b54c3622 100644 --- a/src/main/java/net/fabricmc/loom/configuration/DependencyProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/DependencyProvider.java @@ -49,6 +49,7 @@ import org.zeroturnaround.zip.ZipUtil; import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.LoomGradlePlugin; +import net.fabricmc.loom.configuration.providers.MinecraftProvider; import net.fabricmc.loom.extension.LoomFiles; public abstract class DependencyProvider { @@ -93,6 +94,10 @@ public abstract class DependencyProvider { return getExtension().getFiles(); } + public MinecraftProvider getMinecraftProvider() { + return getExtension().getMinecraftProvider(); + } + public boolean isRefreshDeps() { return LoomGradlePlugin.refreshDeps; } diff --git a/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java b/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java index e3a4c565..c54cdd1c 100644 --- a/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java +++ b/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java @@ -139,7 +139,7 @@ public class LoomDependencyManager { } SourceRemapper sourceRemapper = new SourceRemapper(project, true); - String mappingsKey = mappingsProvider.getMappingsKey(); + String mappingsIdentifier = mappingsProvider.mappingsIdentifier(); if (extension.getInstallerData() == null) { //If we've not found the installer JSON we've probably skipped remapping Fabric loader, let's go looking @@ -168,7 +168,7 @@ public class LoomDependencyManager { project.getLogger().warn("fabric-installer.json not found in classpath!"); } - ModCompileRemapper.remapDependencies(project, mappingsKey, extension, sourceRemapper); + ModCompileRemapper.remapDependencies(project, mappingsIdentifier, extension, sourceRemapper); long start = System.currentTimeMillis(); diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftProcessedProvider.java b/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftProcessedProvider.java index de10ba53..989c5932 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftProcessedProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/MinecraftProcessedProvider.java @@ -66,11 +66,11 @@ public class MinecraftProcessedProvider extends MinecraftMappedProvider { } getProject().getDependencies().add(Constants.Configurations.MINECRAFT_NAMED, - getProject().getDependencies().module("net.minecraft:minecraft:" + getJarVersionString(projectMappedClassifier))); + getProject().getDependencies().module("net.minecraft:minecraft-" + projectMappedClassifier + ":" + getMinecraftProvider().minecraftVersion() + "/" + getExtension().getMappingsProvider().mappingsIdentifier())); } private void invalidateJars() { - File dir = getJarDirectory(getExtension().getFiles().getUserCache(), projectMappedClassifier); + File dir = projectMappedJar.getParentFile(); if (dir.exists()) { getProject().getLogger().warn("Invalidating project jars"); @@ -87,7 +87,8 @@ public class MinecraftProcessedProvider extends MinecraftMappedProvider { public void initFiles(MinecraftProviderImpl minecraftProvider, MappingsProviderImpl mappingsProvider) { super.initFiles(minecraftProvider, mappingsProvider); - projectMappedJar = new File(getJarDirectory(getExtension().getFiles().getRootProjectPersistentCache(), projectMappedClassifier), "minecraft-" + getJarVersionString(projectMappedClassifier) + ".jar"); + projectMappedJar = new File(getDirectories().getRootProjectPersistentCache(), getMinecraftProvider().minecraftVersion() + "/" + + getExtension().getMappingsProvider().mappingsIdentifier() + "/minecraft-" + projectMappedClassifier + ".jar"); } @Override diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/LaunchProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/LaunchProvider.java index b11e0116..d92c784e 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/LaunchProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/LaunchProvider.java @@ -58,8 +58,8 @@ public class LaunchProvider extends DependencyProvider { .property("fabric.remapClasspathFile", getRemapClasspathFile().getAbsolutePath()) .property("log4j.configurationFile", getAllLog4JConfigFiles()) - .property("client", "java.library.path", getDirectories().getNativesDirectory(getExtension().getMinecraftProvider()).getAbsolutePath()) - .property("client", "org.lwjgl.librarypath", getDirectories().getNativesDirectory(getExtension().getMinecraftProvider()).getAbsolutePath()) + .property("client", "java.library.path", getExtension().getMinecraftProvider().nativesDir().getAbsolutePath()) + .property("client", "org.lwjgl.librarypath", getExtension().getMinecraftProvider().nativesDir().getAbsolutePath()) .argument("client", "--assetIndex") .argument("client", getExtension().getMinecraftProvider().getVersionInfo().assetIndex().fabricId(getExtension().getMinecraftProvider().minecraftVersion())) diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/MinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/MinecraftProvider.java index ca493986..96593194 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/MinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/MinecraftProvider.java @@ -24,9 +24,21 @@ package net.fabricmc.loom.configuration.providers; +import java.io.File; + import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta; public interface MinecraftProvider { + File workingDir(); + + boolean hasCustomNatives(); + + File nativesDir(); + + File dir(String path); + + File file(String path); + String minecraftVersion(); MinecraftVersionMeta getVersionInfo(); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/MinecraftProviderImpl.java b/src/main/java/net/fabricmc/loom/configuration/providers/MinecraftProviderImpl.java index 97fa0013..f9a594b5 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/MinecraftProviderImpl.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/MinecraftProviderImpl.java @@ -53,6 +53,7 @@ public class MinecraftProviderImpl extends DependencyProvider implements Minecra private MinecraftVersionMeta versionInfo; private MinecraftLibraryProvider libraryProvider; + private File workingDir; private File minecraftJson; private File minecraftClientJar; private File minecraftServerJar; @@ -112,10 +113,12 @@ public class MinecraftProviderImpl extends DependencyProvider implements Minecra } private void initFiles() { - minecraftJson = new File(getDirectories().getUserCache(), "minecraft-" + minecraftVersion + "-info.json"); - minecraftClientJar = new File(getDirectories().getUserCache(), "minecraft-" + minecraftVersion + "-client.jar"); - minecraftServerJar = new File(getDirectories().getUserCache(), "minecraft-" + minecraftVersion + "-server.jar"); - minecraftMergedJar = new File(getDirectories().getUserCache(), "minecraft-" + minecraftVersion + "-merged.jar"); + workingDir = new File(getDirectories().getUserCache(), minecraftVersion); + workingDir.mkdirs(); + minecraftJson = file("minecraft-info.json"); + minecraftClientJar = file("minecraft-client.jar"); + minecraftServerJar = file("minecraft-server.jar"); + minecraftMergedJar = file("minecraft-merged.jar"); versionManifestJson = new File(getDirectories().getUserCache(), "version_manifest.json"); experimentalVersionsJson = new File(getDirectories().getUserCache(), "experimental_version_manifest.json"); } @@ -257,6 +260,37 @@ public class MinecraftProviderImpl extends DependencyProvider implements Minecra return minecraftMergedJar; } + @Override + public File workingDir() { + return workingDir; + } + + @Override + public boolean hasCustomNatives() { + return getProject().getProperties().get("fabric.loom.natives.dir") != null; + } + + @Override + public File nativesDir() { + if (hasCustomNatives()) { + return new File((String) getProject().property("fabric.loom.natives.dir")); + } + + return dir("natives"); + } + + @Override + public File dir(String path) { + File dir = file(path); + dir.mkdirs(); + return dir; + } + + @Override + public File file(String path) { + return new File(workingDir(), path); + } + @Override public String minecraftVersion() { return minecraftVersion; diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java index e7998e48..e62e9e91 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/GradleMappingContext.java @@ -62,9 +62,7 @@ public class GradleMappingContext implements MappingContext { @Override public File workingDirectory(String name) { - File tempDir = new File(mappingsProvider().getMappingsDir().toFile(), workingDirName); - tempDir.mkdirs(); - return new File(tempDir, name); + return new File(minecraftProvider().dir("layered/working_dir/" + workingDirName), name); } @Override diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java index 1b5d673f..a5ed75b5 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java @@ -64,7 +64,7 @@ public class LayeredMappingsDependency implements SelfResolvingDependency { @Override public Set resolve() { - Path mappingsDir = mappingContext.mappingsProvider().getMappingsDir(); + Path mappingsDir = mappingContext.minecraftProvider().dir("layered").toPath(); Path mappingsFile = mappingsDir.resolve(String.format("%s.%s-%s.tiny", GROUP, MODULE, getVersion())); if (!Files.exists(mappingsFile) || LoomGradlePlugin.refreshDeps) { diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProvider.java index b150a3de..18b8ee89 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProvider.java @@ -28,7 +28,7 @@ import java.io.File; import java.nio.file.Path; public interface MappingsProvider { - Path getMappingsDir(); + Path mappingsWorkingDir(); File intermediaryTinyFile(); } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java index 903d347a..7767741e 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java @@ -28,18 +28,18 @@ import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.nio.file.StandardCopyOption; +import java.util.Collections; import java.util.function.Consumer; -import com.google.common.base.Preconditions; +import com.google.common.base.Stopwatch; import com.google.common.net.UrlEscapers; import com.google.gson.JsonObject; -import org.apache.commons.io.FileUtils; import org.apache.tools.ant.util.StringUtils; import org.gradle.api.Project; import org.zeroturnaround.zip.FileSource; @@ -59,6 +59,11 @@ import net.fabricmc.loom.util.DeletingFileVisitor; import net.fabricmc.loom.util.DownloadUtil; import net.fabricmc.mapping.reader.v2.TinyV2Factory; import net.fabricmc.mapping.tree.TinyTree; +import net.fabricmc.mappingio.adapter.MappingNsCompleter; +import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch; +import net.fabricmc.mappingio.format.Tiny2Reader; +import net.fabricmc.mappingio.format.Tiny2Writer; +import net.fabricmc.mappingio.tree.MemoryMappingTree; import net.fabricmc.stitch.Command; import net.fabricmc.stitch.commands.CommandProposeFieldNames; import net.fabricmc.stitch.commands.tinyv2.CommandMergeTinyV2; @@ -67,35 +72,26 @@ import net.fabricmc.stitch.commands.tinyv2.CommandReorderTinyV2; public class MappingsProviderImpl extends DependencyProvider implements MappingsProvider { public MinecraftMappedProvider mappedProvider; - public String mappingsName; - public String minecraftVersion; - public String mappingsVersion; + public String mappingsIdentifier; - private final Path mappingsDir; - private final Path mappingsStepsDir; + private Path mappingsWorkingDir; private Path intermediaryTiny; private boolean hasRefreshed = false; // The mappings that gradle gives us private Path baseTinyMappings; // The mappings we use in practice - public File tinyMappings; - public File tinyMappingsJar; - private File unpickDefinitionsFile; + public Path tinyMappings; + public Path tinyMappingsJar; + private Path unpickDefinitions; private boolean hasUnpickDefinitions; private UnpickMetadata unpickMetadata; public MappingsProviderImpl(Project project) { super(project); - mappingsDir = getDirectories().getUserCache().toPath().resolve("mappings"); - mappingsStepsDir = mappingsDir.resolve("steps"); - } - - public void clean() throws IOException { - FileUtils.deleteDirectory(mappingsDir.toFile()); } public TinyTree getMappings() throws IOException { - return MappingsCache.INSTANCE.get(tinyMappings.toPath()); + return MappingsCache.INSTANCE.get(tinyMappings); } @Override @@ -107,59 +103,22 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings String version = dependency.getResolvedVersion(); File mappingsJar = dependency.resolveFile().orElseThrow(() -> new RuntimeException("Could not find yarn mappings: " + dependency)); - this.mappingsName = StringUtils.removeSuffix(dependency.getDependency().getGroup() + "." + dependency.getDependency().getName(), "-unmerged"); - this.minecraftVersion = minecraftProvider.minecraftVersion(); - - boolean isV2; - - // Only do this for official yarn, there isn't really a way we can get the mc version for all mappings - if (dependency.getDependency().getGroup() != null && dependency.getDependency().getGroup().equals("net.fabricmc") && dependency.getDependency().getName().equals("yarn") && dependency.getDependency().getVersion() != null) { - String yarnVersion = dependency.getDependency().getVersion(); - char separator = yarnVersion.contains("+build.") ? '+' : yarnVersion.contains("-") ? '-' : '.'; - String yarnMinecraftVersion = yarnVersion.substring(0, yarnVersion.lastIndexOf(separator)); - - if (!yarnMinecraftVersion.equalsIgnoreCase(minecraftVersion)) { - throw new RuntimeException(String.format("Minecraft Version (%s) does not match yarn's minecraft version (%s)", minecraftVersion, yarnMinecraftVersion)); - } - - // We can save reading the zip file + header by checking the file name - isV2 = mappingsJar.getName().endsWith("-v2.jar"); - } else { - isV2 = doesJarContainV2Mappings(mappingsJar.toPath()); - } - - this.mappingsVersion = version + (isV2 ? "-v2" : ""); + String mappingsName = StringUtils.removeSuffix(dependency.getDependency().getGroup() + "." + dependency.getDependency().getName(), "-unmerged"); + boolean isV2 = isV2(dependency, mappingsJar); + this.mappingsIdentifier = createMappingsIdentifier(mappingsName, version, getMappingsClassifier(dependency, isV2)); initFiles(); - if (isRefreshDeps()) { - cleanFiles(); - } - - Files.createDirectories(mappingsDir); - Files.createDirectories(mappingsStepsDir); - - String[] depStringSplit = dependency.getDepString().split(":"); - String jarClassifier = "final"; - - if (depStringSplit.length >= 4) { - jarClassifier = jarClassifier + depStringSplit[3]; - } - - tinyMappings = mappingsDir.resolve(StringUtils.removeSuffix(mappingsJar.getName(), ".jar") + ".tiny").toFile(); - unpickDefinitionsFile = mappingsDir.resolve(StringUtils.removeSuffix(mappingsJar.getName(), ".jar") + ".unpick").toFile(); - tinyMappingsJar = new File(getDirectories().getUserCache(), mappingsJar.getName().replace(".jar", "-" + jarClassifier + ".jar")); - - if (!tinyMappings.exists() || isRefreshDeps()) { + if (Files.notExists(tinyMappings) || isRefreshDeps()) { storeMappings(getProject(), minecraftProvider, mappingsJar.toPath()); } else { try (FileSystem fileSystem = FileSystems.newFileSystem(mappingsJar.toPath(), (ClassLoader) null)) { - extractUnpickDefinitions(fileSystem, unpickDefinitionsFile.toPath()); + extractUnpickDefinitions(fileSystem, unpickDefinitions); } } - if (!tinyMappingsJar.exists() || isRefreshDeps()) { - ZipUtil.pack(new ZipEntrySource[] {new FileSource("mappings/mappings.tiny", tinyMappings)}, tinyMappingsJar); + if (Files.notExists(tinyMappingsJar) || isRefreshDeps()) { + ZipUtil.pack(new ZipEntrySource[] {new FileSource("mappings/mappings.tiny", tinyMappings.toFile())}, tinyMappingsJar.toFile()); } if (hasUnpickDefinitions()) { @@ -173,7 +132,7 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings populateUnpickClasspath(); } - addDependency(tinyMappingsJar, Constants.Configurations.MAPPINGS_FINAL); + addDependency(tinyMappingsJar.toFile(), Constants.Configurations.MAPPINGS_FINAL); LoomGradleExtension extension = getExtension(); @@ -198,30 +157,57 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings mappedProvider.provide(dependency, postPopulationScheduler); } + private String getMappingsClassifier(DependencyInfo dependency, boolean isV2) { + String[] depStringSplit = dependency.getDepString().split(":"); + + if (depStringSplit.length >= 4) { + return "-" + depStringSplit[3] + (isV2 ? "-v2" : ""); + } + + return isV2 ? "-v2" : ""; + } + + private boolean isV2(DependencyInfo dependency, File mappingsJar) throws IOException { + String minecraftVersion = getMinecraftProvider().minecraftVersion(); + + // Only do this for official yarn, there isn't really a way we can get the mc version for all mappings + if (dependency.getDependency().getGroup() != null && dependency.getDependency().getGroup().equals("net.fabricmc") && dependency.getDependency().getName().equals("yarn") && dependency.getDependency().getVersion() != null) { + String yarnVersion = dependency.getDependency().getVersion(); + char separator = yarnVersion.contains("+build.") ? '+' : yarnVersion.contains("-") ? '-' : '.'; + String yarnMinecraftVersion = yarnVersion.substring(0, yarnVersion.lastIndexOf(separator)); + + if (!yarnMinecraftVersion.equalsIgnoreCase(minecraftVersion)) { + throw new RuntimeException(String.format("Minecraft Version (%s) does not match yarn's minecraft version (%s)", minecraftVersion, yarnMinecraftVersion)); + } + + // We can save reading the zip file + header by checking the file name + return mappingsJar.getName().endsWith("-v2.jar"); + } else { + return doesJarContainV2Mappings(mappingsJar.toPath()); + } + } + private void storeMappings(Project project, MinecraftProviderImpl minecraftProvider, Path yarnJar) throws IOException { project.getLogger().info(":extracting " + yarnJar.getFileName()); try (FileSystem fileSystem = FileSystems.newFileSystem(yarnJar, (ClassLoader) null)) { extractMappings(fileSystem, baseTinyMappings); - extractUnpickDefinitions(fileSystem, unpickDefinitionsFile.toPath()); + extractUnpickDefinitions(fileSystem, unpickDefinitions); } - if (baseMappingsAreV2()) { + if (areMappingsV2(baseTinyMappings)) { // These are unmerged v2 mappings - mergeAndSaveMappings(project, yarnJar); + mergeAndSaveMappings(project, baseTinyMappings, tinyMappings); } else { // These are merged v1 mappings - if (tinyMappings.exists()) { - tinyMappings.delete(); - } - + Files.deleteIfExists(tinyMappings); project.getLogger().lifecycle(":populating field names"); - suggestFieldNames(minecraftProvider, baseTinyMappings, tinyMappings.toPath()); + suggestFieldNames(minecraftProvider, baseTinyMappings, tinyMappings); } } - private boolean baseMappingsAreV2() throws IOException { - try (BufferedReader reader = Files.newBufferedReader(baseTinyMappings)) { + private static boolean areMappingsV2(Path path) throws IOException { + try (BufferedReader reader = Files.newBufferedReader(path)) { TinyV2Factory.readMetadata(reader); return true; } catch (IllegalArgumentException e) { @@ -230,7 +216,7 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings } } - private boolean doesJarContainV2Mappings(Path path) throws IOException { + private static boolean doesJarContainV2Mappings(Path path) throws IOException { try (FileSystem fs = FileSystems.newFileSystem(path, (ClassLoader) null)) { try (BufferedReader reader = Files.newBufferedReader(fs.getPath("mappings", "mappings.tiny"))) { TinyV2Factory.readMetadata(reader); @@ -241,6 +227,12 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings } } + private static void extractMappings(Path jar, Path extractTo) throws IOException { + try (FileSystem unmergedIntermediaryFs = FileSystems.newFileSystem(jar, (ClassLoader) null)) { + extractMappings(unmergedIntermediaryFs, extractTo); + } + } + public static void extractMappings(FileSystem jar, Path extractTo) throws IOException { Files.copy(jar.getPath("mappings/mappings.tiny"), extractTo, StandardCopyOption.REPLACE_EXISTING); } @@ -279,28 +271,34 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings ); } - private void extractIntermediary(Path intermediaryJar, Path intermediaryTiny) throws IOException { - getProject().getLogger().info(":extracting " + intermediaryJar.getFileName()); + private void mergeAndSaveMappings(Project project, Path from, Path out) throws IOException { + Stopwatch stopwatch = Stopwatch.createStarted(); + project.getLogger().info(":merging mappings"); - try (FileSystem unmergedIntermediaryFs = FileSystems.newFileSystem(intermediaryJar, (ClassLoader) null)) { - extractMappings(unmergedIntermediaryFs, intermediaryTiny); + MemoryMappingTree tree = new MemoryMappingTree(); + MappingSourceNsSwitch sourceNsSwitch = new MappingSourceNsSwitch(tree, MappingNamespace.OFFICIAL.stringValue()); + readIntermediaryTree().accept(sourceNsSwitch); + + try (BufferedReader reader = Files.newBufferedReader(from, StandardCharsets.UTF_8)) { + Tiny2Reader.read(reader, tree); } + + try (Tiny2Writer writer = new Tiny2Writer(Files.newBufferedWriter(out, StandardCharsets.UTF_8), false)) { + tree.accept(writer); + } + + project.getLogger().info(":merged mappings in " + stopwatch.stop()); } - private void mergeAndSaveMappings(Project project, Path unmergedYarnJar) throws IOException { - Path unmergedYarn = Paths.get(mappingsStepsDir.toString(), "unmerged-yarn.tiny"); - project.getLogger().info(":extracting " + unmergedYarnJar.getFileName()); + private MemoryMappingTree readIntermediaryTree() throws IOException { + MemoryMappingTree tree = new MemoryMappingTree(); + MappingNsCompleter nsCompleter = new MappingNsCompleter(tree, Collections.singletonMap(MappingNamespace.NAMED.stringValue(), MappingNamespace.INTERMEDIARY.stringValue()), true); - try (FileSystem unmergedYarnJarFs = FileSystems.newFileSystem(unmergedYarnJar, (ClassLoader) null)) { - extractMappings(unmergedYarnJarFs, unmergedYarn); + try (BufferedReader reader = Files.newBufferedReader(getIntermediaryTiny(), StandardCharsets.UTF_8)) { + Tiny2Reader.read(reader, nsCompleter); } - Path invertedIntermediary = Paths.get(mappingsStepsDir.toString(), "inverted-intermediary.tiny"); - reorderMappings(getIntermediaryTiny(), invertedIntermediary, "intermediary", "official"); - Path unorderedMergedMappings = Paths.get(mappingsStepsDir.toString(), "unordered-merged.tiny"); - project.getLogger().info(":merging"); - mergeMappings(invertedIntermediary, unmergedYarn, unorderedMergedMappings); - reorderMappings(unorderedMergedMappings, tinyMappings.toPath(), "official", "intermediary", "named"); + return tree; } private void reorderMappings(Path oldMappings, Path newMappings, String... newOrder) { @@ -341,25 +339,21 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings } private void initFiles() { - baseTinyMappings = mappingsDir.resolve(mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion + "-base"); + mappingsWorkingDir = getMinecraftProvider().dir(mappingsIdentifier).toPath(); + baseTinyMappings = mappingsWorkingDir.resolve("mappings-base.tiny"); + tinyMappings = mappingsWorkingDir.resolve("mappings.tiny"); + tinyMappingsJar = mappingsWorkingDir.resolve("mappings.jar"); + unpickDefinitions = mappingsWorkingDir.resolve("mappings.unpick"); + + if (isRefreshDeps()) { + cleanFiles(); + } } public void cleanFiles() { try { - if (Files.exists(mappingsStepsDir)) { - Files.walkFileTree(mappingsStepsDir, new DeletingFileVisitor()); - } - - if (Files.exists(baseTinyMappings)) { - Files.deleteIfExists(baseTinyMappings); - } - - if (tinyMappings != null) { - tinyMappings.delete(); - } - - if (tinyMappingsJar != null) { - tinyMappingsJar.delete(); + if (Files.exists(mappingsWorkingDir)) { + Files.walkFileTree(mappingsWorkingDir, new DeletingFileVisitor()); } } catch (IOException e) { e.printStackTrace(); @@ -371,40 +365,42 @@ public class MappingsProviderImpl extends DependencyProvider implements Mappings return Constants.Configurations.MAPPINGS; } - @Override - public Path getMappingsDir() { - return mappingsDir; - } - public Path getIntermediaryTiny() throws IOException { if (intermediaryTiny == null) { - minecraftVersion = getExtension().getMinecraftProvider().minecraftVersion(); - Preconditions.checkNotNull(minecraftVersion, "Minecraft version cannot be null"); - - intermediaryTiny = mappingsDir.resolve(String.format("intermediary-%s-v2.tiny", minecraftVersion)); + intermediaryTiny = getMinecraftProvider().file("intermediary-v2.tiny").toPath(); if (!Files.exists(intermediaryTiny) || (isRefreshDeps() && !hasRefreshed)) { hasRefreshed = true; // Download and extract intermediary - String encodedMinecraftVersion = UrlEscapers.urlFragmentEscaper().escape(minecraftVersion); + String encodedMinecraftVersion = UrlEscapers.urlFragmentEscaper().escape(getMinecraftProvider().minecraftVersion()); String intermediaryArtifactUrl = getExtension().getIntermediaryUrl(encodedMinecraftVersion); - Path intermediaryJar = mappingsDir.resolve("v2-intermediary-" + minecraftVersion + ".jar"); - DownloadUtil.downloadIfChanged(new URL(intermediaryArtifactUrl), intermediaryJar.toFile(), getProject().getLogger()); - - extractIntermediary(intermediaryJar, intermediaryTiny); + File intermediaryJar = getMinecraftProvider().file("intermediary-v2.jar"); + DownloadUtil.downloadIfChanged(new URL(intermediaryArtifactUrl), intermediaryJar, getProject().getLogger()); + extractMappings(intermediaryJar.toPath(), intermediaryTiny); } } return intermediaryTiny; } - public String getMappingsKey() { - return mappingsName + "." + minecraftVersion.replace(' ', '_').replace('.', '_').replace('-', '_') + "." + mappingsVersion; + @Override + public Path mappingsWorkingDir() { + return mappingsWorkingDir; + } + + private String createMappingsIdentifier(String mappingsName, String version, String classifier) { + // mappingsName . mcVersion . version classifier + // Example: net.fabricmc.yarn . 1_16_5 . 1.16.5+build.5 -v2 + return mappingsName + "." + getMinecraftProvider().minecraftVersion().replace(' ', '_').replace('.', '_').replace('-', '_') + "." + version + classifier; + } + + public String mappingsIdentifier() { + return mappingsIdentifier; } public File getUnpickDefinitionsFile() { - return unpickDefinitionsFile; + return unpickDefinitions.toFile(); } public boolean hasUnpickDefinitions() { diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java index 1892a324..b95f8195 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftMappedProvider.java @@ -61,7 +61,7 @@ public class MinecraftMappedProvider extends DependencyProvider { @Override public void provide(DependencyInfo dependency, Consumer postPopulationScheduler) throws Exception { - if (!getExtension().getMappingsProvider().tinyMappings.exists()) { + if (Files.notExists(getExtension().getMappingsProvider().tinyMappings)) { throw new RuntimeException("mappings file not found"); } @@ -145,13 +145,13 @@ public class MinecraftMappedProvider extends DependencyProvider { protected void addDependencies(DependencyInfo dependency, Consumer postPopulationScheduler) { getProject().getDependencies().add(Constants.Configurations.MINECRAFT_NAMED, - getProject().getDependencies().module("net.minecraft:minecraft:" + getJarVersionString("mapped"))); + getProject().getDependencies().module("net.minecraft:minecraft-mapped:" + getMinecraftProvider().minecraftVersion() + "/" + getExtension().getMappingsProvider().mappingsIdentifier())); } public void initFiles(MinecraftProviderImpl minecraftProvider, MappingsProviderImpl mappingsProvider) { this.minecraftProvider = minecraftProvider; - minecraftIntermediaryJar = new File(getDirectories().getUserCache(), "minecraft-" + getJarVersionString("intermediary") + ".jar"); - minecraftMappedJar = new File(getJarDirectory(getDirectories().getUserCache(), "mapped"), "minecraft-" + getJarVersionString("mapped") + ".jar"); + minecraftIntermediaryJar = new File(getExtension().getMappingsProvider().mappingsWorkingDir().toFile(), "minecraft-intermediary.jar"); + minecraftMappedJar = new File(getExtension().getMappingsProvider().mappingsWorkingDir().toFile(), "minecraft-mapped.jar"); } protected File getJarDirectory(File parentDirectory, String type) { @@ -159,7 +159,7 @@ public class MinecraftMappedProvider extends DependencyProvider { } protected String getJarVersionString(String type) { - return String.format("%s-%s-%s-%s", minecraftProvider.minecraftVersion(), type, getExtension().getMappingsProvider().mappingsName, getExtension().getMappingsProvider().mappingsVersion); + return String.format("%s-%s", type, getExtension().getMappingsProvider().mappingsIdentifier()); } public File getIntermediaryJar() { @@ -171,7 +171,7 @@ public class MinecraftMappedProvider extends DependencyProvider { } public File getUnpickedJar() { - return new File(getJarDirectory(getDirectories().getUserCache(), "mapped"), "minecraft-" + getJarVersionString("unpicked") + ".jar"); + return new File(getExtension().getMappingsProvider().mappingsWorkingDir().toFile(), "minecraft-unpicked.jar"); } @Override diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftNativesProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftNativesProvider.java index 868b5651..3cda63e7 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftNativesProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftNativesProvider.java @@ -51,7 +51,7 @@ public class MinecraftNativesProvider { this.project = project; extension = LoomGradleExtension.get(project); - nativesDir = extension.getFiles().getNativesDirectory(extension.getMinecraftProvider()); + nativesDir = extension.getMinecraftProvider().nativesDir(); jarStore = extension.getFiles().getNativesJarStore(); } @@ -60,7 +60,7 @@ public class MinecraftNativesProvider { } private void provide() throws IOException { - if (extension.getFiles().hasCustomNatives()) { + if (extension.getMinecraftProvider().hasCustomNatives()) { if (!nativesDir.exists()) { throw new RuntimeException("Could no find custom natives directory at " + nativesDir.getAbsolutePath()); } diff --git a/src/main/java/net/fabricmc/loom/extension/LoomFiles.java b/src/main/java/net/fabricmc/loom/extension/LoomFiles.java index c93e0272..66307c18 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomFiles.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomFiles.java @@ -29,8 +29,6 @@ import java.io.File; import org.gradle.api.Project; import org.gradle.api.initialization.Settings; -import net.fabricmc.loom.configuration.providers.MinecraftProvider; - public interface LoomFiles { static LoomFiles create(Project project) { return new LoomFilesProjectImpl(project); @@ -46,8 +44,6 @@ public interface LoomFiles { File getProjectBuildCache(); File getRemappedModCache(); File getNativesJarStore(); - boolean hasCustomNatives(); - File getNativesDirectory(MinecraftProvider minecraftProvider); File getDefaultLog4jConfigFile(); File getDevLauncherConfig(); File getUnpickLoggingConfigFile(); diff --git a/src/main/java/net/fabricmc/loom/extension/LoomFilesProjectImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomFilesProjectImpl.java index b047dc1f..3a5897e5 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomFilesProjectImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomFilesProjectImpl.java @@ -29,8 +29,6 @@ import java.util.Objects; import org.gradle.api.Project; -import net.fabricmc.loom.configuration.providers.MinecraftProvider; - public final class LoomFilesProjectImpl extends LoomFilesBaseImpl { private final Project project; @@ -57,24 +55,4 @@ public final class LoomFilesProjectImpl extends LoomFilesBaseImpl { protected File getBuildDir() { return project.getBuildDir(); } - - @Override - public boolean hasCustomNatives() { - return project.getProperties().get("fabric.loom.natives.dir") != null; - } - - @Override - public File getNativesDirectory(MinecraftProvider minecraftProvider) { - if (hasCustomNatives()) { - return new File((String) project.property("fabric.loom.natives.dir")); - } - - File natives = new File(getUserCache(), "natives/" + minecraftProvider.minecraftVersion()); - - if (!natives.exists()) { - natives.mkdirs(); - } - - return natives; - } } diff --git a/src/main/java/net/fabricmc/loom/extension/LoomFilesSettingsImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomFilesSettingsImpl.java index 7e12b0cb..6597ad17 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomFilesSettingsImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomFilesSettingsImpl.java @@ -29,8 +29,6 @@ import java.util.Objects; import org.gradle.api.initialization.Settings; -import net.fabricmc.loom.configuration.providers.MinecraftProvider; - public class LoomFilesSettingsImpl extends LoomFilesBaseImpl { private final Settings settings; @@ -38,16 +36,6 @@ public class LoomFilesSettingsImpl extends LoomFilesBaseImpl { this.settings = Objects.requireNonNull(settings); } - @Override - public boolean hasCustomNatives() { - return false; - } - - @Override - public File getNativesDirectory(MinecraftProvider minecraftProvider) { - throw new IllegalStateException("You can not access natives directory from setting stage"); - } - @Override protected File getGradleUserHomeDir() { return settings.getGradle().getGradleUserHomeDir(); diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java index 408e396f..00cb2f9a 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java @@ -107,7 +107,7 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA LayeredMappingSpecBuilder builder = new LayeredMappingSpecBuilder(); action.execute(builder); LayeredMappingSpec builtSpec = builder.build(); - return new LayeredMappingsDependency(new GradleMappingContext(getProject(), "layers_" + builtSpec.getVersion().replace("+", "_").replace(".", "_")), builtSpec, builtSpec.getVersion()); + return new LayeredMappingsDependency(new GradleMappingContext(getProject(), builtSpec.getVersion().replace("+", "_").replace(".", "_")), builtSpec, builtSpec.getVersion()); } @Override diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java index 323495c4..98510b3c 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java @@ -81,7 +81,7 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen @Override public synchronized File getNextMixinMappings() { - File mixinMapping = new File(getFiles().getProjectBuildCache(), "mixin-map-" + getMinecraftProvider().minecraftVersion() + "-" + getMappingsProvider().mappingsVersion + "." + mixinMappings.size() + ".tiny"); + File mixinMapping = new File(getFiles().getProjectBuildCache(), "mixin-map-" + getMappingsProvider().mappingsIdentifier() + "." + mixinMappings.size() + ".tiny"); mixinMappings.add(mixinMapping); return mixinMapping; } diff --git a/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java b/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java index 4c833cfe..9bde07b4 100644 --- a/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java +++ b/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java @@ -62,7 +62,7 @@ public class GenerateSourcesTask extends AbstractLoomTask { @TaskAction public void doTask() throws Throwable { int threads = Runtime.getRuntime().availableProcessors(); - Path javaDocs = getExtension().getMappingsProvider().tinyMappings.toPath(); + Path javaDocs = getExtension().getMappingsProvider().tinyMappings; Collection libraries = getProject().getConfigurations().getByName(Constants.Configurations.MINECRAFT_DEPENDENCIES).getFiles() .stream().map(File::toPath).collect(Collectors.toSet()); diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/UnpickTest.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/UnpickTest.groovy index b4162db0..6254f441 100644 --- a/src/test/groovy/net/fabricmc/loom/test/integration/UnpickTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/integration/UnpickTest.groovy @@ -33,7 +33,7 @@ import java.nio.charset.StandardCharsets import static org.gradle.testkit.runner.TaskOutcome.SUCCESS class UnpickTest extends Specification implements ProjectTestTrait { - static final String MAPPINGS = "21w13a-mapped-net.fabricmc.yarn-21w13a+build.30-v2" + static final String MAPPINGS = "21w13a/net.fabricmc.yarn.21w13a.21w13a+build.30-v2" @Override String name() { diff --git a/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy b/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy index 02e1e4f4..f48b95b4 100644 --- a/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/util/ProjectTestTrait.groovy @@ -121,6 +121,6 @@ trait ProjectTestTrait { } File getGeneratedSources(String mappings, String gradleVersion = DEFAULT_GRADLE) { - return new File(gradleHomeDirectory(gradleVersion), "caches/fabric-loom/${mappings}/minecraft-${mappings}-sources.jar") + return new File(gradleHomeDirectory(gradleVersion), "caches/fabric-loom/${mappings}/minecraft-mapped-sources.jar") } } \ No newline at end of file