Basic layered mappings with @ParchmentMC support (#413)
parent
e179cccf64
commit
1f9f48052b
|
@ -45,6 +45,7 @@ configurations {
|
||||||
}
|
}
|
||||||
compileClasspath.extendsFrom bootstrap
|
compileClasspath.extendsFrom bootstrap
|
||||||
runtimeClasspath.extendsFrom bootstrap
|
runtimeClasspath.extendsFrom bootstrap
|
||||||
|
testRuntimeClasspath.extendsFrom bootstrap
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -74,6 +75,7 @@ dependencies {
|
||||||
implementation ('net.fabricmc:tiny-mappings-parser:0.3.0+build.17')
|
implementation ('net.fabricmc:tiny-mappings-parser:0.3.0+build.17')
|
||||||
|
|
||||||
implementation 'net.fabricmc:access-widener:1.0.0'
|
implementation 'net.fabricmc:access-widener:1.0.0'
|
||||||
|
implementation 'net.fabricmc:mapping-io:0.1.3'
|
||||||
|
|
||||||
implementation ('net.fabricmc:lorenz-tiny:3.0.0') {
|
implementation ('net.fabricmc:lorenz-tiny:3.0.0') {
|
||||||
transitive = false
|
transitive = false
|
||||||
|
@ -92,7 +94,7 @@ dependencies {
|
||||||
|
|
||||||
// Testing
|
// Testing
|
||||||
testImplementation(gradleTestKit())
|
testImplementation(gradleTestKit())
|
||||||
testImplementation('org.spockframework:spock-core:2.0-M5-groovy-3.0') {
|
testImplementation('org.spockframework:spock-core:2.0-groovy-3.0') {
|
||||||
exclude module: 'groovy-all'
|
exclude module: 'groovy-all'
|
||||||
}
|
}
|
||||||
testImplementation 'io.javalin:javalin:3.13.7'
|
testImplementation 'io.javalin:javalin:3.13.7'
|
||||||
|
|
|
@ -52,10 +52,13 @@ import net.fabricmc.loom.configuration.LoomProjectData;
|
||||||
import net.fabricmc.loom.configuration.ide.RunConfigSettings;
|
import net.fabricmc.loom.configuration.ide.RunConfigSettings;
|
||||||
import net.fabricmc.loom.configuration.processors.JarProcessor;
|
import net.fabricmc.loom.configuration.processors.JarProcessor;
|
||||||
import net.fabricmc.loom.configuration.processors.JarProcessorManager;
|
import net.fabricmc.loom.configuration.processors.JarProcessorManager;
|
||||||
import net.fabricmc.loom.configuration.providers.MinecraftProvider;
|
import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl;
|
||||||
import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider;
|
|
||||||
import net.fabricmc.loom.configuration.providers.mappings.MojangMappingsDependency;
|
|
||||||
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider;
|
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider;
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.GradleMappingContext;
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpec;
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilder;
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsDependency;
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
|
||||||
|
|
||||||
public class LoomGradleExtension {
|
public class LoomGradleExtension {
|
||||||
public String refmapName;
|
public String refmapName;
|
||||||
|
@ -114,7 +117,14 @@ public class LoomGradleExtension {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dependency officialMojangMappings() {
|
public Dependency officialMojangMappings() {
|
||||||
return new MojangMappingsDependency(project, this);
|
return layered(LayeredMappingSpecBuilder::officalMojangMappings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dependency layered(Action<LayeredMappingSpecBuilder> action) {
|
||||||
|
LayeredMappingSpecBuilder builder = new LayeredMappingSpecBuilder();
|
||||||
|
action.execute(builder);
|
||||||
|
LayeredMappingSpec builtSpec = builder.build();
|
||||||
|
return new LayeredMappingsDependency(new GradleMappingContext(project, "layers_" + builtSpec.getVersion().replace("+", "_").replace(".", "_")), builtSpec, builtSpec.getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoomGradleExtension(Project project) {
|
public LoomGradleExtension(Project project) {
|
||||||
|
@ -246,7 +256,7 @@ public class LoomGradleExtension {
|
||||||
return new File((String) project.property("fabric.loom.natives.dir"));
|
return new File((String) project.property("fabric.loom.natives.dir"));
|
||||||
}
|
}
|
||||||
|
|
||||||
File natives = new File(getUserCache(), "natives/" + getMinecraftProvider().getMinecraftVersion());
|
File natives = new File(getUserCache(), "natives/" + getMinecraftProvider().minecraftVersion());
|
||||||
|
|
||||||
if (!natives.exists()) {
|
if (!natives.exists()) {
|
||||||
natives.mkdirs();
|
natives.mkdirs();
|
||||||
|
@ -271,16 +281,16 @@ public class LoomGradleExtension {
|
||||||
return dependencyManager;
|
return dependencyManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MinecraftProvider getMinecraftProvider() {
|
public MinecraftProviderImpl getMinecraftProvider() {
|
||||||
return getDependencyManager().getProvider(MinecraftProvider.class);
|
return getDependencyManager().getProvider(MinecraftProviderImpl.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MinecraftMappedProvider getMinecraftMappedProvider() {
|
public MinecraftMappedProvider getMinecraftMappedProvider() {
|
||||||
return getMappingsProvider().mappedProvider;
|
return getMappingsProvider().mappedProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MappingsProvider getMappingsProvider() {
|
public MappingsProviderImpl getMappingsProvider() {
|
||||||
return getDependencyManager().getProvider(MappingsProvider.class);
|
return getDependencyManager().getProvider(MappingsProviderImpl.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDependencyManager(LoomDependencyManager dependencyManager) {
|
public void setDependencyManager(LoomDependencyManager dependencyManager) {
|
||||||
|
@ -342,7 +352,7 @@ public class LoomGradleExtension {
|
||||||
// Creates a new file each time its called, this is then held onto later when remapping the output jar
|
// Creates a new file each time its called, this is then held onto later when remapping the output jar
|
||||||
// Required as now when using parallel builds the old single file could be written by another sourceset compile task
|
// Required as now when using parallel builds the old single file could be written by another sourceset compile task
|
||||||
public synchronized File getNextMixinMappings() {
|
public synchronized File getNextMixinMappings() {
|
||||||
File mixinMapping = new File(getProjectBuildCache(), "mixin-map-" + getMinecraftProvider().getMinecraftVersion() + "-" + getMappingsProvider().mappingsVersion + "." + mixinMappings.size() + ".tiny");
|
File mixinMapping = new File(getProjectBuildCache(), "mixin-map-" + getMinecraftProvider().minecraftVersion() + "-" + getMappingsProvider().mappingsVersion + "." + mixinMappings.size() + ".tiny");
|
||||||
mixinMappings.add(mixinMapping);
|
mixinMappings.add(mixinMapping);
|
||||||
return mixinMapping;
|
return mixinMapping;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,8 +39,8 @@ import net.fabricmc.loom.build.mixin.KaptApInvoker;
|
||||||
import net.fabricmc.loom.build.mixin.ScalaApInvoker;
|
import net.fabricmc.loom.build.mixin.ScalaApInvoker;
|
||||||
import net.fabricmc.loom.configuration.ide.SetupIntelijRunConfigs;
|
import net.fabricmc.loom.configuration.ide.SetupIntelijRunConfigs;
|
||||||
import net.fabricmc.loom.configuration.providers.LaunchProvider;
|
import net.fabricmc.loom.configuration.providers.LaunchProvider;
|
||||||
import net.fabricmc.loom.configuration.providers.MinecraftProvider;
|
import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl;
|
||||||
import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider;
|
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
|
||||||
import net.fabricmc.loom.util.Constants;
|
import net.fabricmc.loom.util.Constants;
|
||||||
|
|
||||||
public final class CompileConfiguration {
|
public final class CompileConfiguration {
|
||||||
|
@ -116,8 +116,8 @@ public final class CompileConfiguration {
|
||||||
LoomDependencyManager dependencyManager = new LoomDependencyManager();
|
LoomDependencyManager dependencyManager = new LoomDependencyManager();
|
||||||
extension.setDependencyManager(dependencyManager);
|
extension.setDependencyManager(dependencyManager);
|
||||||
|
|
||||||
dependencyManager.addProvider(new MinecraftProvider(project));
|
dependencyManager.addProvider(new MinecraftProviderImpl(project));
|
||||||
dependencyManager.addProvider(new MappingsProvider(project));
|
dependencyManager.addProvider(new MappingsProviderImpl(project));
|
||||||
dependencyManager.addProvider(new LaunchProvider(project));
|
dependencyManager.addProvider(new LaunchProvider(project));
|
||||||
|
|
||||||
dependencyManager.handleDependencies(project);
|
dependencyManager.handleDependencies(project);
|
||||||
|
|
|
@ -42,7 +42,7 @@ import net.fabricmc.loom.LoomGradleExtension;
|
||||||
import net.fabricmc.loom.build.ModCompileRemapper;
|
import net.fabricmc.loom.build.ModCompileRemapper;
|
||||||
import net.fabricmc.loom.configuration.DependencyProvider.DependencyInfo;
|
import net.fabricmc.loom.configuration.DependencyProvider.DependencyInfo;
|
||||||
import net.fabricmc.loom.configuration.mods.ModProcessor;
|
import net.fabricmc.loom.configuration.mods.ModProcessor;
|
||||||
import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider;
|
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
|
||||||
import net.fabricmc.loom.util.Constants;
|
import net.fabricmc.loom.util.Constants;
|
||||||
import net.fabricmc.loom.util.SourceRemapper;
|
import net.fabricmc.loom.util.SourceRemapper;
|
||||||
import net.fabricmc.loom.LoomRepositoryPlugin;
|
import net.fabricmc.loom.LoomRepositoryPlugin;
|
||||||
|
@ -86,7 +86,7 @@ public class LoomDependencyManager {
|
||||||
public void handleDependencies(Project project) {
|
public void handleDependencies(Project project) {
|
||||||
List<Runnable> afterTasks = new ArrayList<>();
|
List<Runnable> afterTasks = new ArrayList<>();
|
||||||
|
|
||||||
MappingsProvider mappingsProvider = null;
|
MappingsProviderImpl mappingsProvider = null;
|
||||||
|
|
||||||
project.getLogger().info(":setting up loom dependencies");
|
project.getLogger().info(":setting up loom dependencies");
|
||||||
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
||||||
|
@ -100,8 +100,8 @@ public class LoomDependencyManager {
|
||||||
return list;
|
return list;
|
||||||
}).providers.add(provider);
|
}).providers.add(provider);
|
||||||
|
|
||||||
if (provider instanceof MappingsProvider) {
|
if (provider instanceof MappingsProviderImpl) {
|
||||||
mappingsProvider = (MappingsProvider) provider;
|
mappingsProvider = (MappingsProviderImpl) provider;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ import net.fabricmc.loom.LoomGradleExtension;
|
||||||
import net.fabricmc.loom.LoomGradlePlugin;
|
import net.fabricmc.loom.LoomGradlePlugin;
|
||||||
import net.fabricmc.loom.configuration.RemappedConfigurationEntry;
|
import net.fabricmc.loom.configuration.RemappedConfigurationEntry;
|
||||||
import net.fabricmc.loom.configuration.processors.dependency.ModDependencyInfo;
|
import net.fabricmc.loom.configuration.processors.dependency.ModDependencyInfo;
|
||||||
import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider;
|
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
|
||||||
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider;
|
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider;
|
||||||
import net.fabricmc.loom.util.Constants;
|
import net.fabricmc.loom.util.Constants;
|
||||||
import net.fabricmc.loom.util.TinyRemapperMappingsHelper;
|
import net.fabricmc.loom.util.TinyRemapperMappingsHelper;
|
||||||
|
@ -132,7 +132,7 @@ public class ModProcessor {
|
||||||
String toM = "named";
|
String toM = "named";
|
||||||
|
|
||||||
MinecraftMappedProvider mappedProvider = extension.getMinecraftMappedProvider();
|
MinecraftMappedProvider mappedProvider = extension.getMinecraftMappedProvider();
|
||||||
MappingsProvider mappingsProvider = extension.getMappingsProvider();
|
MappingsProviderImpl mappingsProvider = extension.getMappingsProvider();
|
||||||
|
|
||||||
Path mc = mappedProvider.getIntermediaryJar().toPath();
|
Path mc = mappedProvider.getIntermediaryJar().toPath();
|
||||||
Path[] mcDeps = project.getConfigurations().getByName(Constants.Configurations.LOADER_DEPENDENCIES).getFiles()
|
Path[] mcDeps = project.getConfigurations().getByName(Constants.Configurations.LOADER_DEPENDENCIES).getFiles()
|
||||||
|
|
|
@ -31,8 +31,8 @@ import java.util.function.Consumer;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.gradle.api.Project;
|
import org.gradle.api.Project;
|
||||||
|
|
||||||
import net.fabricmc.loom.configuration.providers.MinecraftProvider;
|
import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl;
|
||||||
import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider;
|
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
|
||||||
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider;
|
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider;
|
||||||
import net.fabricmc.loom.util.Constants;
|
import net.fabricmc.loom.util.Constants;
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ public class MinecraftProcessedProvider extends MinecraftMappedProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initFiles(MinecraftProvider minecraftProvider, MappingsProvider mappingsProvider) {
|
public void initFiles(MinecraftProviderImpl minecraftProvider, MappingsProviderImpl mappingsProvider) {
|
||||||
super.initFiles(minecraftProvider, mappingsProvider);
|
super.initFiles(minecraftProvider, mappingsProvider);
|
||||||
|
|
||||||
projectMappedJar = new File(getJarDirectory(getExtension().getRootProjectPersistentCache(), projectMappedClassifier), "minecraft-" + getJarVersionString(projectMappedClassifier) + ".jar");
|
projectMappedJar = new File(getJarDirectory(getExtension().getRootProjectPersistentCache(), projectMappedClassifier), "minecraft-" + getJarVersionString(projectMappedClassifier) + ".jar");
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class LaunchProvider extends DependencyProvider {
|
||||||
.property("client", "org.lwjgl.librarypath", getExtension().getNativesDirectory().getAbsolutePath())
|
.property("client", "org.lwjgl.librarypath", getExtension().getNativesDirectory().getAbsolutePath())
|
||||||
|
|
||||||
.argument("client", "--assetIndex")
|
.argument("client", "--assetIndex")
|
||||||
.argument("client", getExtension().getMinecraftProvider().getVersionInfo().assetIndex().fabricId(getExtension().getMinecraftProvider().getMinecraftVersion()))
|
.argument("client", getExtension().getMinecraftProvider().getVersionInfo().assetIndex().fabricId(getExtension().getMinecraftProvider().minecraftVersion()))
|
||||||
.argument("client", "--assetsDir")
|
.argument("client", "--assetsDir")
|
||||||
.argument("client", new File(getExtension().getUserCache(), "assets").getAbsolutePath());
|
.argument("client", new File(getExtension().getUserCache(), "assets").getAbsolutePath());
|
||||||
|
|
||||||
|
|
|
@ -24,224 +24,10 @@
|
||||||
|
|
||||||
package net.fabricmc.loom.configuration.providers;
|
package net.fabricmc.loom.configuration.providers;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import com.google.common.io.Files;
|
|
||||||
import org.gradle.api.GradleException;
|
|
||||||
import org.gradle.api.Project;
|
|
||||||
import org.gradle.api.logging.Logger;
|
|
||||||
|
|
||||||
import net.fabricmc.loom.LoomGradlePlugin;
|
|
||||||
import net.fabricmc.loom.configuration.DependencyProvider;
|
|
||||||
import net.fabricmc.loom.configuration.providers.minecraft.ManifestVersion;
|
|
||||||
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftLibraryProvider;
|
|
||||||
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta;
|
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta;
|
||||||
import net.fabricmc.loom.util.Constants;
|
|
||||||
import net.fabricmc.loom.util.DownloadUtil;
|
|
||||||
import net.fabricmc.loom.util.HashedDownloadUtil;
|
|
||||||
import net.fabricmc.stitch.merge.JarMerger;
|
|
||||||
|
|
||||||
public class MinecraftProvider extends DependencyProvider {
|
public interface MinecraftProvider {
|
||||||
private String minecraftVersion;
|
String minecraftVersion();
|
||||||
|
|
||||||
private MinecraftVersionMeta versionInfo;
|
MinecraftVersionMeta getVersionInfo();
|
||||||
private MinecraftLibraryProvider libraryProvider;
|
|
||||||
|
|
||||||
private File minecraftJson;
|
|
||||||
private File minecraftClientJar;
|
|
||||||
private File minecraftServerJar;
|
|
||||||
private File minecraftMergedJar;
|
|
||||||
private File versionManifestJson;
|
|
||||||
|
|
||||||
public MinecraftProvider(Project project) {
|
|
||||||
super(project);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void provide(DependencyInfo dependency, Consumer<Runnable> postPopulationScheduler) throws Exception {
|
|
||||||
minecraftVersion = dependency.getDependency().getVersion();
|
|
||||||
|
|
||||||
boolean offline = getProject().getGradle().getStartParameter().isOffline();
|
|
||||||
|
|
||||||
initFiles();
|
|
||||||
|
|
||||||
downloadMcJson(offline);
|
|
||||||
|
|
||||||
try (FileReader reader = new FileReader(minecraftJson)) {
|
|
||||||
versionInfo = LoomGradlePlugin.OBJECT_MAPPER.readValue(reader, MinecraftVersionMeta.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add Loom as an annotation processor
|
|
||||||
addDependency(getProject().files(this.getClass().getProtectionDomain().getCodeSource().getLocation()), "compileOnly");
|
|
||||||
|
|
||||||
if (offline) {
|
|
||||||
if (minecraftClientJar.exists() && minecraftServerJar.exists()) {
|
|
||||||
getProject().getLogger().debug("Found client and server jars, presuming up-to-date");
|
|
||||||
} else if (minecraftMergedJar.exists()) {
|
|
||||||
//Strictly we don't need the split jars if the merged one exists, let's try go on
|
|
||||||
getProject().getLogger().warn("Missing game jar but merged jar present, things might end badly");
|
|
||||||
} else {
|
|
||||||
throw new GradleException("Missing jar(s); Client: " + minecraftClientJar.exists() + ", Server: " + minecraftServerJar.exists());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
downloadJars(getProject().getLogger());
|
|
||||||
}
|
|
||||||
|
|
||||||
libraryProvider = new MinecraftLibraryProvider();
|
|
||||||
libraryProvider.provide(this, getProject());
|
|
||||||
|
|
||||||
if (!minecraftMergedJar.exists() || isRefreshDeps()) {
|
|
||||||
try {
|
|
||||||
mergeJars(getProject().getLogger());
|
|
||||||
} catch (Throwable e) {
|
|
||||||
HashedDownloadUtil.delete(minecraftClientJar);
|
|
||||||
HashedDownloadUtil.delete(minecraftServerJar);
|
|
||||||
minecraftMergedJar.delete();
|
|
||||||
|
|
||||||
getProject().getLogger().error("Could not merge JARs! Deleting source JARs - please re-run the command and move on.", e);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initFiles() {
|
|
||||||
minecraftJson = new File(getExtension().getUserCache(), "minecraft-" + minecraftVersion + "-info.json");
|
|
||||||
minecraftClientJar = new File(getExtension().getUserCache(), "minecraft-" + minecraftVersion + "-client.jar");
|
|
||||||
minecraftServerJar = new File(getExtension().getUserCache(), "minecraft-" + minecraftVersion + "-server.jar");
|
|
||||||
minecraftMergedJar = new File(getExtension().getUserCache(), "minecraft-" + minecraftVersion + "-merged.jar");
|
|
||||||
versionManifestJson = new File(getExtension().getUserCache(), "version_manifest.json");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void downloadMcJson(boolean offline) throws IOException {
|
|
||||||
if (getExtension().isShareCaches() && !getExtension().isRootProject() && versionManifestJson.exists() && !isRefreshDeps()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!offline && !isRefreshDeps() && hasRecentValidManifest()) {
|
|
||||||
// We have a recent valid manifest file, so do nothing
|
|
||||||
} else if (offline) {
|
|
||||||
if (versionManifestJson.exists()) {
|
|
||||||
// If there is the manifests already we'll presume that's good enough
|
|
||||||
getProject().getLogger().debug("Found version manifests, presuming up-to-date");
|
|
||||||
} else {
|
|
||||||
// If we don't have the manifests then there's nothing more we can do
|
|
||||||
throw new GradleException("Version manifests not found at " + versionManifestJson.getAbsolutePath());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
getProject().getLogger().debug("Downloading version manifests");
|
|
||||||
DownloadUtil.downloadIfChanged(new URL(Constants.VERSION_MANIFESTS), versionManifestJson, getProject().getLogger());
|
|
||||||
}
|
|
||||||
|
|
||||||
String versionManifest = Files.asCharSource(versionManifestJson, StandardCharsets.UTF_8).read();
|
|
||||||
ManifestVersion mcManifest = LoomGradlePlugin.OBJECT_MAPPER.readValue(versionManifest, ManifestVersion.class);
|
|
||||||
|
|
||||||
Optional<ManifestVersion.Versions> optionalVersion = Optional.empty();
|
|
||||||
|
|
||||||
if (getExtension().customManifest != null) {
|
|
||||||
ManifestVersion.Versions customVersion = new ManifestVersion.Versions();
|
|
||||||
customVersion.id = minecraftVersion;
|
|
||||||
customVersion.url = getExtension().customManifest;
|
|
||||||
optionalVersion = Optional.of(customVersion);
|
|
||||||
getProject().getLogger().lifecycle("Using custom minecraft manifest");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!optionalVersion.isPresent()) {
|
|
||||||
optionalVersion = mcManifest.versions().stream().filter(versions -> versions.id.equalsIgnoreCase(minecraftVersion)).findFirst();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (optionalVersion.isPresent()) {
|
|
||||||
if (offline) {
|
|
||||||
if (minecraftJson.exists()) {
|
|
||||||
//If there is the manifest already we'll presume that's good enough
|
|
||||||
getProject().getLogger().debug("Found Minecraft {} manifest, presuming up-to-date", minecraftVersion);
|
|
||||||
} else {
|
|
||||||
//If we don't have the manifests then there's nothing more we can do
|
|
||||||
throw new GradleException("Minecraft " + minecraftVersion + " manifest not found at " + minecraftJson.getAbsolutePath());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
getProject().getLogger().debug("Downloading Minecraft {} manifest", minecraftVersion);
|
|
||||||
|
|
||||||
ManifestVersion.Versions version = optionalVersion.get();
|
|
||||||
String url = version.url;
|
|
||||||
|
|
||||||
if (version.sha1 != null) {
|
|
||||||
HashedDownloadUtil.downloadIfInvalid(new URL(url), minecraftJson, version.sha1, getProject().getLogger(), true);
|
|
||||||
} else {
|
|
||||||
// Use the etag if no hash found from url
|
|
||||||
DownloadUtil.downloadIfChanged(new URL(url), minecraftJson, getProject().getLogger());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException("Failed to find minecraft version: " + minecraftVersion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasRecentValidManifest() throws IOException {
|
|
||||||
if (getExtension().customManifest != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!versionManifestJson.exists() || !minecraftJson.exists()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (versionManifestJson.lastModified() > System.currentTimeMillis() - 24 * 3_600_000) {
|
|
||||||
// Version manifest hasn't been modified in 24 hours, time to get a new one.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ManifestVersion manifest = LoomGradlePlugin.OBJECT_MAPPER.readValue(Files.asCharSource(versionManifestJson, StandardCharsets.UTF_8).read(), ManifestVersion.class);
|
|
||||||
Optional<ManifestVersion.Versions> version = manifest.versions().stream().filter(versions -> versions.id.equalsIgnoreCase(minecraftVersion)).findFirst();
|
|
||||||
|
|
||||||
// fail if the expected mc version was not found, will download the file again.
|
|
||||||
return version.isPresent();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void downloadJars(Logger logger) throws IOException {
|
|
||||||
if (getExtension().isShareCaches() && !getExtension().isRootProject() && minecraftClientJar.exists() && minecraftServerJar.exists() && !isRefreshDeps()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MinecraftVersionMeta.Download client = versionInfo.download("client");
|
|
||||||
MinecraftVersionMeta.Download server = versionInfo.download("server");
|
|
||||||
|
|
||||||
HashedDownloadUtil.downloadIfInvalid(new URL(client.url()), minecraftClientJar, client.sha1(), logger, false);
|
|
||||||
HashedDownloadUtil.downloadIfInvalid(new URL(server.url()), minecraftServerJar, server.sha1(), logger, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void mergeJars(Logger logger) throws IOException {
|
|
||||||
logger.info(":merging jars");
|
|
||||||
|
|
||||||
try (JarMerger jarMerger = new JarMerger(minecraftClientJar, minecraftServerJar, minecraftMergedJar)) {
|
|
||||||
jarMerger.enableSyntheticParamsOffset();
|
|
||||||
jarMerger.merge();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getMergedJar() {
|
|
||||||
return minecraftMergedJar;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMinecraftVersion() {
|
|
||||||
return minecraftVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MinecraftVersionMeta getVersionInfo() {
|
|
||||||
return versionInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MinecraftLibraryProvider getLibraryProvider() {
|
|
||||||
return libraryProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTargetConfig() {
|
|
||||||
return Constants.Configurations.MINECRAFT;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,249 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.configuration.providers;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import com.google.common.io.Files;
|
||||||
|
import org.gradle.api.GradleException;
|
||||||
|
import org.gradle.api.Project;
|
||||||
|
import org.gradle.api.logging.Logger;
|
||||||
|
|
||||||
|
import net.fabricmc.loom.LoomGradlePlugin;
|
||||||
|
import net.fabricmc.loom.configuration.DependencyProvider;
|
||||||
|
import net.fabricmc.loom.configuration.providers.minecraft.ManifestVersion;
|
||||||
|
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftLibraryProvider;
|
||||||
|
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta;
|
||||||
|
import net.fabricmc.loom.util.Constants;
|
||||||
|
import net.fabricmc.loom.util.DownloadUtil;
|
||||||
|
import net.fabricmc.loom.util.HashedDownloadUtil;
|
||||||
|
import net.fabricmc.stitch.merge.JarMerger;
|
||||||
|
|
||||||
|
public class MinecraftProviderImpl extends DependencyProvider implements MinecraftProvider {
|
||||||
|
private String minecraftVersion;
|
||||||
|
|
||||||
|
private MinecraftVersionMeta versionInfo;
|
||||||
|
private MinecraftLibraryProvider libraryProvider;
|
||||||
|
|
||||||
|
private File minecraftJson;
|
||||||
|
private File minecraftClientJar;
|
||||||
|
private File minecraftServerJar;
|
||||||
|
private File minecraftMergedJar;
|
||||||
|
private File versionManifestJson;
|
||||||
|
|
||||||
|
public MinecraftProviderImpl(Project project) {
|
||||||
|
super(project);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void provide(DependencyInfo dependency, Consumer<Runnable> postPopulationScheduler) throws Exception {
|
||||||
|
minecraftVersion = dependency.getDependency().getVersion();
|
||||||
|
|
||||||
|
boolean offline = getProject().getGradle().getStartParameter().isOffline();
|
||||||
|
|
||||||
|
initFiles();
|
||||||
|
|
||||||
|
downloadMcJson(offline);
|
||||||
|
|
||||||
|
try (FileReader reader = new FileReader(minecraftJson)) {
|
||||||
|
versionInfo = LoomGradlePlugin.OBJECT_MAPPER.readValue(reader, MinecraftVersionMeta.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add Loom as an annotation processor
|
||||||
|
addDependency(getProject().files(this.getClass().getProtectionDomain().getCodeSource().getLocation()), "compileOnly");
|
||||||
|
|
||||||
|
if (offline) {
|
||||||
|
if (minecraftClientJar.exists() && minecraftServerJar.exists()) {
|
||||||
|
getProject().getLogger().debug("Found client and server jars, presuming up-to-date");
|
||||||
|
} else if (minecraftMergedJar.exists()) {
|
||||||
|
//Strictly we don't need the split jars if the merged one exists, let's try go on
|
||||||
|
getProject().getLogger().warn("Missing game jar but merged jar present, things might end badly");
|
||||||
|
} else {
|
||||||
|
throw new GradleException("Missing jar(s); Client: " + minecraftClientJar.exists() + ", Server: " + minecraftServerJar.exists());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
downloadJars(getProject().getLogger());
|
||||||
|
}
|
||||||
|
|
||||||
|
libraryProvider = new MinecraftLibraryProvider();
|
||||||
|
libraryProvider.provide(this, getProject());
|
||||||
|
|
||||||
|
if (!minecraftMergedJar.exists() || isRefreshDeps()) {
|
||||||
|
try {
|
||||||
|
mergeJars(getProject().getLogger());
|
||||||
|
} catch (Throwable e) {
|
||||||
|
HashedDownloadUtil.delete(minecraftClientJar);
|
||||||
|
HashedDownloadUtil.delete(minecraftServerJar);
|
||||||
|
minecraftMergedJar.delete();
|
||||||
|
|
||||||
|
getProject().getLogger().error("Could not merge JARs! Deleting source JARs - please re-run the command and move on.", e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initFiles() {
|
||||||
|
minecraftJson = new File(getExtension().getUserCache(), "minecraft-" + minecraftVersion + "-info.json");
|
||||||
|
minecraftClientJar = new File(getExtension().getUserCache(), "minecraft-" + minecraftVersion + "-client.jar");
|
||||||
|
minecraftServerJar = new File(getExtension().getUserCache(), "minecraft-" + minecraftVersion + "-server.jar");
|
||||||
|
minecraftMergedJar = new File(getExtension().getUserCache(), "minecraft-" + minecraftVersion + "-merged.jar");
|
||||||
|
versionManifestJson = new File(getExtension().getUserCache(), "version_manifest.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void downloadMcJson(boolean offline) throws IOException {
|
||||||
|
if (getExtension().isShareCaches() && !getExtension().isRootProject() && versionManifestJson.exists() && !isRefreshDeps()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!offline && !isRefreshDeps() && hasRecentValidManifest()) {
|
||||||
|
// We have a recent valid manifest file, so do nothing
|
||||||
|
} else if (offline) {
|
||||||
|
if (versionManifestJson.exists()) {
|
||||||
|
// If there is the manifests already we'll presume that's good enough
|
||||||
|
getProject().getLogger().debug("Found version manifests, presuming up-to-date");
|
||||||
|
} else {
|
||||||
|
// If we don't have the manifests then there's nothing more we can do
|
||||||
|
throw new GradleException("Version manifests not found at " + versionManifestJson.getAbsolutePath());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
getProject().getLogger().debug("Downloading version manifests");
|
||||||
|
DownloadUtil.downloadIfChanged(new URL(Constants.VERSION_MANIFESTS), versionManifestJson, getProject().getLogger());
|
||||||
|
}
|
||||||
|
|
||||||
|
String versionManifest = Files.asCharSource(versionManifestJson, StandardCharsets.UTF_8).read();
|
||||||
|
ManifestVersion mcManifest = LoomGradlePlugin.OBJECT_MAPPER.readValue(versionManifest, ManifestVersion.class);
|
||||||
|
|
||||||
|
Optional<ManifestVersion.Versions> optionalVersion = Optional.empty();
|
||||||
|
|
||||||
|
if (getExtension().customManifest != null) {
|
||||||
|
ManifestVersion.Versions customVersion = new ManifestVersion.Versions();
|
||||||
|
customVersion.id = minecraftVersion;
|
||||||
|
customVersion.url = getExtension().customManifest;
|
||||||
|
optionalVersion = Optional.of(customVersion);
|
||||||
|
getProject().getLogger().lifecycle("Using custom minecraft manifest");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!optionalVersion.isPresent()) {
|
||||||
|
optionalVersion = mcManifest.versions().stream().filter(versions -> versions.id.equalsIgnoreCase(minecraftVersion)).findFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optionalVersion.isPresent()) {
|
||||||
|
if (offline) {
|
||||||
|
if (minecraftJson.exists()) {
|
||||||
|
//If there is the manifest already we'll presume that's good enough
|
||||||
|
getProject().getLogger().debug("Found Minecraft {} manifest, presuming up-to-date", minecraftVersion);
|
||||||
|
} else {
|
||||||
|
//If we don't have the manifests then there's nothing more we can do
|
||||||
|
throw new GradleException("Minecraft " + minecraftVersion + " manifest not found at " + minecraftJson.getAbsolutePath());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
getProject().getLogger().debug("Downloading Minecraft {} manifest", minecraftVersion);
|
||||||
|
|
||||||
|
ManifestVersion.Versions version = optionalVersion.get();
|
||||||
|
String url = version.url;
|
||||||
|
|
||||||
|
if (version.sha1 != null) {
|
||||||
|
HashedDownloadUtil.downloadIfInvalid(new URL(url), minecraftJson, version.sha1, getProject().getLogger(), true);
|
||||||
|
} else {
|
||||||
|
// Use the etag if no hash found from url
|
||||||
|
DownloadUtil.downloadIfChanged(new URL(url), minecraftJson, getProject().getLogger());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Failed to find minecraft version: " + minecraftVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasRecentValidManifest() throws IOException {
|
||||||
|
if (getExtension().customManifest != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!versionManifestJson.exists() || !minecraftJson.exists()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (versionManifestJson.lastModified() > System.currentTimeMillis() - 24 * 3_600_000) {
|
||||||
|
// Version manifest hasn't been modified in 24 hours, time to get a new one.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ManifestVersion manifest = LoomGradlePlugin.OBJECT_MAPPER.readValue(Files.asCharSource(versionManifestJson, StandardCharsets.UTF_8).read(), ManifestVersion.class);
|
||||||
|
Optional<ManifestVersion.Versions> version = manifest.versions().stream().filter(versions -> versions.id.equalsIgnoreCase(minecraftVersion)).findFirst();
|
||||||
|
|
||||||
|
// fail if the expected mc version was not found, will download the file again.
|
||||||
|
return version.isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void downloadJars(Logger logger) throws IOException {
|
||||||
|
if (getExtension().isShareCaches() && !getExtension().isRootProject() && minecraftClientJar.exists() && minecraftServerJar.exists() && !isRefreshDeps()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MinecraftVersionMeta.Download client = versionInfo.download("client");
|
||||||
|
MinecraftVersionMeta.Download server = versionInfo.download("server");
|
||||||
|
|
||||||
|
HashedDownloadUtil.downloadIfInvalid(new URL(client.url()), minecraftClientJar, client.sha1(), logger, false);
|
||||||
|
HashedDownloadUtil.downloadIfInvalid(new URL(server.url()), minecraftServerJar, server.sha1(), logger, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mergeJars(Logger logger) throws IOException {
|
||||||
|
logger.info(":merging jars");
|
||||||
|
|
||||||
|
try (JarMerger jarMerger = new JarMerger(minecraftClientJar, minecraftServerJar, minecraftMergedJar)) {
|
||||||
|
jarMerger.enableSyntheticParamsOffset();
|
||||||
|
jarMerger.merge();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getMergedJar() {
|
||||||
|
return minecraftMergedJar;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String minecraftVersion() {
|
||||||
|
return minecraftVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MinecraftVersionMeta getVersionInfo() {
|
||||||
|
return versionInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MinecraftLibraryProvider getLibraryProvider() {
|
||||||
|
return libraryProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTargetConfig() {
|
||||||
|
return Constants.Configurations.MINECRAFT;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.configuration.providers.mappings;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import org.gradle.api.Project;
|
||||||
|
import org.gradle.api.artifacts.Configuration;
|
||||||
|
import org.gradle.api.logging.Logger;
|
||||||
|
|
||||||
|
import net.fabricmc.loom.LoomGradleExtension;
|
||||||
|
import net.fabricmc.loom.configuration.providers.MinecraftProvider;
|
||||||
|
|
||||||
|
public class GradleMappingContext implements MappingContext {
|
||||||
|
private final Project project;
|
||||||
|
private final LoomGradleExtension extension;
|
||||||
|
private final String workingDirName;
|
||||||
|
|
||||||
|
public GradleMappingContext(Project project, String workingDirName) {
|
||||||
|
this.project = project;
|
||||||
|
this.extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
||||||
|
this.workingDirName = workingDirName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File mavenFile(String mavenNotation) {
|
||||||
|
Configuration configuration = project.getConfigurations().detachedConfiguration(project.getDependencies().create(mavenNotation));
|
||||||
|
return configuration.getSingleFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappingsProvider mappingsProvider() {
|
||||||
|
return extension.getMappingsProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MinecraftProvider minecraftProvider() {
|
||||||
|
return extension.getMinecraftProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File workingDirectory(String name) {
|
||||||
|
File tempDir = new File(mappingsProvider().getMappingsDir().toFile(), workingDirName);
|
||||||
|
tempDir.mkdirs();
|
||||||
|
return new File(tempDir, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Logger getLogger() {
|
||||||
|
return project.getLogger();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.configuration.providers.mappings;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public record LayeredMappingSpec(List<MappingsSpec<?>> layers) {
|
||||||
|
public String getVersion() {
|
||||||
|
// TODO something better?
|
||||||
|
return "layered+hash.%d".formatted(Math.abs(hashCode()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.configuration.providers.mappings;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.gradle.api.Action;
|
||||||
|
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec;
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsSpec;
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.parchment.ParchmentMappingsSpecBuilder;
|
||||||
|
|
||||||
|
public class LayeredMappingSpecBuilder {
|
||||||
|
private final List<MappingsSpec<?>> layers = new LinkedList<>();
|
||||||
|
|
||||||
|
public LayeredMappingSpecBuilder officalMojangMappings() {
|
||||||
|
layers.add(new MojangMappingsSpec());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LayeredMappingSpecBuilder parchment(String mavenNotation) {
|
||||||
|
parchment(mavenNotation, parchmentMappingsSpecBuilder -> parchmentMappingsSpecBuilder.setRemovePrefix(true));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LayeredMappingSpecBuilder parchment(String mavenNotation, Action<ParchmentMappingsSpecBuilder> action) {
|
||||||
|
var builder = ParchmentMappingsSpecBuilder.builder(mavenNotation);
|
||||||
|
action.execute(builder);
|
||||||
|
layers.add(builder.build());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LayeredMappingSpec build() {
|
||||||
|
List<MappingsSpec<?>> builtLayers = new LinkedList<>();
|
||||||
|
// Intermediary is always the base layer
|
||||||
|
builtLayers.add(new IntermediaryMappingsSpec());
|
||||||
|
builtLayers.addAll(layers);
|
||||||
|
|
||||||
|
return new LayeredMappingSpec(Collections.unmodifiableList(builtLayers));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.configuration.providers.mappings;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.gradle.api.artifacts.Dependency;
|
||||||
|
import org.gradle.api.artifacts.SelfResolvingDependency;
|
||||||
|
import org.gradle.api.tasks.TaskDependency;
|
||||||
|
import org.zeroturnaround.zip.ByteSource;
|
||||||
|
import org.zeroturnaround.zip.ZipEntrySource;
|
||||||
|
import org.zeroturnaround.zip.ZipUtil;
|
||||||
|
|
||||||
|
import net.fabricmc.loom.LoomGradlePlugin;
|
||||||
|
import net.fabricmc.mappingio.adapter.MappingDstNsReorder;
|
||||||
|
import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch;
|
||||||
|
import net.fabricmc.mappingio.format.Tiny2Writer;
|
||||||
|
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
||||||
|
|
||||||
|
public class LayeredMappingsDependency implements SelfResolvingDependency {
|
||||||
|
private static final String GROUP = "loom";
|
||||||
|
private static final String MODULE = "mappings";
|
||||||
|
|
||||||
|
private final MappingContext mappingContext;
|
||||||
|
private final LayeredMappingSpec layeredMappingSpec;
|
||||||
|
private final String version;
|
||||||
|
|
||||||
|
public LayeredMappingsDependency(MappingContext mappingContext, LayeredMappingSpec layeredMappingSpec, String version) {
|
||||||
|
this.mappingContext = mappingContext;
|
||||||
|
this.layeredMappingSpec = layeredMappingSpec;
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<File> resolve() {
|
||||||
|
Path mappingsDir = mappingContext.mappingsProvider().getMappingsDir();
|
||||||
|
Path mappingsFile = mappingsDir.resolve(String.format("%s.%s-%s.tiny", GROUP, MODULE, getVersion()));
|
||||||
|
|
||||||
|
if (!Files.exists(mappingsFile) || LoomGradlePlugin.refreshDeps) {
|
||||||
|
try {
|
||||||
|
var processor = new LayeredMappingsProcessor(layeredMappingSpec);
|
||||||
|
MemoryMappingTree mappings = processor.getMappings(mappingContext);
|
||||||
|
|
||||||
|
try (Writer writer = new StringWriter()) {
|
||||||
|
Tiny2Writer tiny2Writer = new Tiny2Writer(writer, false);
|
||||||
|
|
||||||
|
MappingDstNsReorder nsReorder = new MappingDstNsReorder(tiny2Writer, Collections.singletonList(MappingNamespace.NAMED.stringValue()));
|
||||||
|
MappingSourceNsSwitch nsSwitch = new MappingSourceNsSwitch(nsReorder, MappingNamespace.INTERMEDIARY.stringValue());
|
||||||
|
mappings.accept(nsSwitch);
|
||||||
|
|
||||||
|
Files.deleteIfExists(mappingsFile);
|
||||||
|
|
||||||
|
ZipUtil.pack(new ZipEntrySource[] {
|
||||||
|
new ByteSource("mappings/mappings.tiny", writer.toString().getBytes(StandardCharsets.UTF_8))
|
||||||
|
}, mappingsFile.toFile());
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Failed to resolve Mojang mappings", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Collections.singleton(mappingsFile.toFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<File> resolve(boolean transitive) {
|
||||||
|
return resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TaskDependency getBuildDependencies() {
|
||||||
|
return task -> Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getGroup() {
|
||||||
|
return GROUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return MODULE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contentEquals(Dependency dependency) {
|
||||||
|
if (dependency instanceof LayeredMappingsDependency layeredMappingsDependency) {
|
||||||
|
return Objects.equals(layeredMappingsDependency.getVersion(), this.getVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dependency copy() {
|
||||||
|
return new LayeredMappingsDependency(mappingContext, layeredMappingSpec, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getReason() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void because(String s) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.configuration.providers.mappings;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch;
|
||||||
|
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
||||||
|
|
||||||
|
public class LayeredMappingsProcessor {
|
||||||
|
private final LayeredMappingSpec layeredMappingSpec;
|
||||||
|
|
||||||
|
public LayeredMappingsProcessor(LayeredMappingSpec spec) {
|
||||||
|
this.layeredMappingSpec = spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MemoryMappingTree getMappings(MappingContext context) throws IOException {
|
||||||
|
MemoryMappingTree mappingTree = new MemoryMappingTree();
|
||||||
|
|
||||||
|
List<Class<? extends MappingLayer>> visitedLayers = new ArrayList<>();
|
||||||
|
|
||||||
|
for (MappingsSpec<?> spec : layeredMappingSpec.layers()) {
|
||||||
|
MappingLayer layer = spec.createLayer(context);
|
||||||
|
|
||||||
|
for (Class<? extends MappingLayer> dependentLayer : layer.dependsOn()) {
|
||||||
|
if (!visitedLayers.contains(dependentLayer)) {
|
||||||
|
throw new RuntimeException("Layer %s depends on %s".formatted(layer.getClass().getName(), dependentLayer.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visitedLayers.add(layer.getClass());
|
||||||
|
|
||||||
|
// We have to rebuild a new tree to work on when a layer doesnt merge into layered
|
||||||
|
boolean rebuild = layer.getSourceNamespace() != MappingNamespace.NAMED;
|
||||||
|
MemoryMappingTree workingTree;
|
||||||
|
|
||||||
|
if (rebuild) {
|
||||||
|
var tempTree = new MemoryMappingTree();
|
||||||
|
|
||||||
|
// This can be null on the first layer
|
||||||
|
if (mappingTree.getSrcNamespace() != null) {
|
||||||
|
var sourceNsSwitch = new MappingSourceNsSwitch(tempTree, layer.getSourceNamespace().stringValue());
|
||||||
|
mappingTree.accept(sourceNsSwitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
workingTree = tempTree;
|
||||||
|
} else {
|
||||||
|
workingTree = mappingTree;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
layer.visit(workingTree);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new IOException("Failed to visit: " + layer.getClass(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rebuild) {
|
||||||
|
mappingTree = new MemoryMappingTree();
|
||||||
|
workingTree.accept(new MappingSourceNsSwitch(mappingTree, MappingNamespace.NAMED.stringValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mappingTree;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.configuration.providers.mappings;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import org.gradle.api.logging.Logger;
|
||||||
|
|
||||||
|
import net.fabricmc.loom.configuration.providers.MinecraftProvider;
|
||||||
|
|
||||||
|
public interface MappingContext {
|
||||||
|
File mavenFile(String mavenNotation);
|
||||||
|
|
||||||
|
MappingsProvider mappingsProvider();
|
||||||
|
|
||||||
|
MinecraftProvider minecraftProvider();
|
||||||
|
|
||||||
|
default String minecraftVersion() {
|
||||||
|
return minecraftProvider().minecraftVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a temporary working dir to be used to store working files.
|
||||||
|
*/
|
||||||
|
File workingDirectory(String name);
|
||||||
|
|
||||||
|
Logger getLogger();
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.configuration.providers.mappings;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.fabricmc.mappingio.MappingVisitor;
|
||||||
|
|
||||||
|
public interface MappingLayer {
|
||||||
|
void visit(MappingVisitor mappingVisitor) throws IOException;
|
||||||
|
|
||||||
|
default MappingNamespace getSourceNamespace() {
|
||||||
|
return MappingNamespace.NAMED;
|
||||||
|
}
|
||||||
|
|
||||||
|
default List<Class<? extends MappingLayer>> dependsOn() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.configuration.providers.mappings;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public enum MappingNamespace {
|
||||||
|
OFFICIAL,
|
||||||
|
INTERMEDIARY,
|
||||||
|
NAMED;
|
||||||
|
|
||||||
|
public String stringValue() {
|
||||||
|
return name().toLowerCase(Locale.ROOT);
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,390 +24,11 @@
|
||||||
|
|
||||||
package net.fabricmc.loom.configuration.providers.mappings;
|
package net.fabricmc.loom.configuration.providers.mappings;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.nio.file.FileSystem;
|
|
||||||
import java.nio.file.FileSystems;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.nio.file.StandardCopyOption;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
public interface MappingsProvider {
|
||||||
import com.google.common.net.UrlEscapers;
|
Path getMappingsDir();
|
||||||
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;
|
|
||||||
import org.zeroturnaround.zip.ZipEntrySource;
|
|
||||||
import org.zeroturnaround.zip.ZipUtil;
|
|
||||||
|
|
||||||
import net.fabricmc.loom.LoomGradleExtension;
|
File intermediaryTinyFile();
|
||||||
import net.fabricmc.loom.LoomGradlePlugin;
|
|
||||||
import net.fabricmc.loom.configuration.DependencyProvider;
|
|
||||||
import net.fabricmc.loom.configuration.accesswidener.AccessWidenerJarProcessor;
|
|
||||||
import net.fabricmc.loom.configuration.processors.JarProcessorManager;
|
|
||||||
import net.fabricmc.loom.configuration.processors.MinecraftProcessedProvider;
|
|
||||||
import net.fabricmc.loom.configuration.providers.MinecraftProvider;
|
|
||||||
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider;
|
|
||||||
import net.fabricmc.loom.util.Constants;
|
|
||||||
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.stitch.Command;
|
|
||||||
import net.fabricmc.stitch.commands.CommandProposeFieldNames;
|
|
||||||
import net.fabricmc.stitch.commands.tinyv2.CommandMergeTinyV2;
|
|
||||||
import net.fabricmc.stitch.commands.tinyv2.CommandReorderTinyV2;
|
|
||||||
|
|
||||||
public class MappingsProvider extends DependencyProvider {
|
|
||||||
public MinecraftMappedProvider mappedProvider;
|
|
||||||
|
|
||||||
public String mappingsName;
|
|
||||||
public String minecraftVersion;
|
|
||||||
public String mappingsVersion;
|
|
||||||
|
|
||||||
private final Path mappingsDir;
|
|
||||||
private final Path mappingsStepsDir;
|
|
||||||
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;
|
|
||||||
private boolean hasUnpickDefinitions;
|
|
||||||
private UnpickMetadata unpickMetadata;
|
|
||||||
|
|
||||||
public MappingsProvider(Project project) {
|
|
||||||
super(project);
|
|
||||||
mappingsDir = getExtension().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());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void provide(DependencyInfo dependency, Consumer<Runnable> postPopulationScheduler) throws Exception {
|
|
||||||
MinecraftProvider minecraftProvider = getDependencyManager().getProvider(MinecraftProvider.class);
|
|
||||||
|
|
||||||
getProject().getLogger().info(":setting up mappings (" + dependency.getDependency().getName() + " " + dependency.getResolvedVersion() + ")");
|
|
||||||
|
|
||||||
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.getMinecraftVersion();
|
|
||||||
|
|
||||||
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" : "");
|
|
||||||
|
|
||||||
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(getExtension().getUserCache(), mappingsJar.getName().replace(".jar", "-" + jarClassifier + ".jar"));
|
|
||||||
|
|
||||||
if (!tinyMappings.exists() || isRefreshDeps()) {
|
|
||||||
storeMappings(getProject(), minecraftProvider, mappingsJar.toPath());
|
|
||||||
} else {
|
|
||||||
try (FileSystem fileSystem = FileSystems.newFileSystem(mappingsJar.toPath(), (ClassLoader) null)) {
|
|
||||||
extractUnpickDefinitions(fileSystem, unpickDefinitionsFile.toPath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tinyMappingsJar.exists() || isRefreshDeps()) {
|
|
||||||
ZipUtil.pack(new ZipEntrySource[] {new FileSource("mappings/mappings.tiny", tinyMappings)}, tinyMappingsJar);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasUnpickDefinitions()) {
|
|
||||||
String notation = String.format("%s:%s:%s:constants",
|
|
||||||
dependency.getDependency().getGroup(),
|
|
||||||
dependency.getDependency().getName(),
|
|
||||||
dependency.getDependency().getVersion()
|
|
||||||
);
|
|
||||||
|
|
||||||
getProject().getDependencies().add(Constants.Configurations.MAPPING_CONSTANTS, notation);
|
|
||||||
populateUnpickClasspath();
|
|
||||||
}
|
|
||||||
|
|
||||||
addDependency(tinyMappingsJar, Constants.Configurations.MAPPINGS_FINAL);
|
|
||||||
|
|
||||||
LoomGradleExtension extension = getExtension();
|
|
||||||
|
|
||||||
if (extension.accessWidener != null) {
|
|
||||||
extension.addJarProcessor(new AccessWidenerJarProcessor(getProject()));
|
|
||||||
}
|
|
||||||
|
|
||||||
JarProcessorManager processorManager = new JarProcessorManager(extension.getJarProcessors());
|
|
||||||
extension.setJarProcessorManager(processorManager);
|
|
||||||
processorManager.setupProcessors();
|
|
||||||
|
|
||||||
if (processorManager.active()) {
|
|
||||||
mappedProvider = new MinecraftProcessedProvider(getProject(), processorManager);
|
|
||||||
getProject().getLogger().lifecycle("Using project based jar storage");
|
|
||||||
} else {
|
|
||||||
mappedProvider = new MinecraftMappedProvider(getProject());
|
|
||||||
}
|
|
||||||
|
|
||||||
mappedProvider.initFiles(minecraftProvider, this);
|
|
||||||
mappedProvider.provide(dependency, postPopulationScheduler);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void storeMappings(Project project, MinecraftProvider 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());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (baseMappingsAreV2()) {
|
|
||||||
// These are unmerged v2 mappings
|
|
||||||
mergeAndSaveMappings(project, yarnJar);
|
|
||||||
} else {
|
|
||||||
// These are merged v1 mappings
|
|
||||||
if (tinyMappings.exists()) {
|
|
||||||
tinyMappings.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
project.getLogger().lifecycle(":populating field names");
|
|
||||||
suggestFieldNames(minecraftProvider, baseTinyMappings, tinyMappings.toPath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean baseMappingsAreV2() throws IOException {
|
|
||||||
try (BufferedReader reader = Files.newBufferedReader(baseTinyMappings)) {
|
|
||||||
TinyV2Factory.readMetadata(reader);
|
|
||||||
return true;
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
// TODO: just check the mappings version when Parser supports V1 in readMetadata()
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private 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);
|
|
||||||
return true;
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void extractMappings(FileSystem jar, Path extractTo) throws IOException {
|
|
||||||
Files.copy(jar.getPath("mappings/mappings.tiny"), extractTo, StandardCopyOption.REPLACE_EXISTING);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void extractUnpickDefinitions(FileSystem jar, Path extractTo) throws IOException {
|
|
||||||
Path unpickPath = jar.getPath("extras/definitions.unpick");
|
|
||||||
Path unpickMetadataPath = jar.getPath("extras/unpick.json");
|
|
||||||
|
|
||||||
if (!Files.exists(unpickPath) || !Files.exists(unpickMetadataPath)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Files.copy(unpickPath, extractTo, StandardCopyOption.REPLACE_EXISTING);
|
|
||||||
|
|
||||||
unpickMetadata = parseUnpickMetadata(unpickMetadataPath);
|
|
||||||
hasUnpickDefinitions = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private UnpickMetadata parseUnpickMetadata(Path input) throws IOException {
|
|
||||||
JsonObject jsonObject = LoomGradlePlugin.GSON.fromJson(Files.readString(input), JsonObject.class);
|
|
||||||
|
|
||||||
if (!jsonObject.has("version") || jsonObject.get("version").getAsInt() != 1) {
|
|
||||||
throw new UnsupportedOperationException("Unsupported unpick version");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new UnpickMetadata(
|
|
||||||
jsonObject.get("unpickGroup").getAsString(),
|
|
||||||
jsonObject.get("unpickVersion").getAsString()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void populateUnpickClasspath() {
|
|
||||||
String unpickCliName = "unpick-cli";
|
|
||||||
getProject().getDependencies().add(Constants.Configurations.UNPICK_CLASSPATH,
|
|
||||||
String.format("%s:%s:%s", unpickMetadata.unpickGroup, unpickCliName, unpickMetadata.unpickVersion)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void extractIntermediary(Path intermediaryJar, Path intermediaryTiny) throws IOException {
|
|
||||||
getProject().getLogger().info(":extracting " + intermediaryJar.getFileName());
|
|
||||||
|
|
||||||
try (FileSystem unmergedIntermediaryFs = FileSystems.newFileSystem(intermediaryJar, (ClassLoader) null)) {
|
|
||||||
extractMappings(unmergedIntermediaryFs, intermediaryTiny);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void mergeAndSaveMappings(Project project, Path unmergedYarnJar) throws IOException {
|
|
||||||
Path unmergedYarn = Paths.get(mappingsStepsDir.toString(), "unmerged-yarn.tiny");
|
|
||||||
project.getLogger().info(":extracting " + unmergedYarnJar.getFileName());
|
|
||||||
|
|
||||||
try (FileSystem unmergedYarnJarFs = FileSystems.newFileSystem(unmergedYarnJar, (ClassLoader) null)) {
|
|
||||||
extractMappings(unmergedYarnJarFs, unmergedYarn);
|
|
||||||
}
|
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void reorderMappings(Path oldMappings, Path newMappings, String... newOrder) {
|
|
||||||
Command command = new CommandReorderTinyV2();
|
|
||||||
String[] args = new String[2 + newOrder.length];
|
|
||||||
args[0] = oldMappings.toAbsolutePath().toString();
|
|
||||||
args[1] = newMappings.toAbsolutePath().toString();
|
|
||||||
System.arraycopy(newOrder, 0, args, 2, newOrder.length);
|
|
||||||
runCommand(command, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void mergeMappings(Path intermediaryMappings, Path yarnMappings, Path newMergedMappings) {
|
|
||||||
try {
|
|
||||||
Command command = new CommandMergeTinyV2();
|
|
||||||
runCommand(command, intermediaryMappings.toAbsolutePath().toString(),
|
|
||||||
yarnMappings.toAbsolutePath().toString(),
|
|
||||||
newMergedMappings.toAbsolutePath().toString(),
|
|
||||||
"intermediary", "official");
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Could not merge mappings from " + intermediaryMappings.toString()
|
|
||||||
+ " with mappings from " + yarnMappings, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void suggestFieldNames(MinecraftProvider minecraftProvider, Path oldMappings, Path newMappings) {
|
|
||||||
Command command = new CommandProposeFieldNames();
|
|
||||||
runCommand(command, minecraftProvider.getMergedJar().getAbsolutePath(),
|
|
||||||
oldMappings.toAbsolutePath().toString(),
|
|
||||||
newMappings.toAbsolutePath().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void runCommand(Command command, String... args) {
|
|
||||||
try {
|
|
||||||
command.run(args);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initFiles() {
|
|
||||||
baseTinyMappings = mappingsDir.resolve(mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion + "-base");
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTargetConfig() {
|
|
||||||
return Constants.Configurations.MAPPINGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Path getMappingsDir() {
|
|
||||||
return mappingsDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Path getIntermediaryTiny() throws IOException {
|
|
||||||
if (intermediaryTiny == null) {
|
|
||||||
minecraftVersion = getExtension().getMinecraftProvider().getMinecraftVersion();
|
|
||||||
Preconditions.checkNotNull(minecraftVersion, "Minecraft version cannot be null");
|
|
||||||
|
|
||||||
intermediaryTiny = mappingsDir.resolve(String.format("intermediary-%s-v2.tiny", minecraftVersion));
|
|
||||||
|
|
||||||
if (!Files.exists(intermediaryTiny) || (isRefreshDeps() && !hasRefreshed)) {
|
|
||||||
hasRefreshed = true;
|
|
||||||
|
|
||||||
// Download and extract intermediary
|
|
||||||
String encodedMinecraftVersion = UrlEscapers.urlFragmentEscaper().escape(minecraftVersion);
|
|
||||||
String intermediaryArtifactUrl = getExtension().getIntermediaryUrl().apply(encodedMinecraftVersion);
|
|
||||||
Path intermediaryJar = mappingsDir.resolve("v2-intermediary-" + minecraftVersion + ".jar");
|
|
||||||
DownloadUtil.downloadIfChanged(new URL(intermediaryArtifactUrl), intermediaryJar.toFile(), getProject().getLogger());
|
|
||||||
|
|
||||||
extractIntermediary(intermediaryJar, intermediaryTiny);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return intermediaryTiny;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMappingsKey() {
|
|
||||||
return mappingsName + "." + minecraftVersion.replace(' ', '_').replace('.', '_').replace('-', '_') + "." + mappingsVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getUnpickDefinitionsFile() {
|
|
||||||
return unpickDefinitionsFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasUnpickDefinitions() {
|
|
||||||
return hasUnpickDefinitions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public record UnpickMetadata(String unpickGroup, String unpickVersion) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,423 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.configuration.providers.mappings;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
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.function.Consumer;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
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;
|
||||||
|
import org.zeroturnaround.zip.ZipEntrySource;
|
||||||
|
import org.zeroturnaround.zip.ZipUtil;
|
||||||
|
|
||||||
|
import net.fabricmc.loom.LoomGradleExtension;
|
||||||
|
import net.fabricmc.loom.LoomGradlePlugin;
|
||||||
|
import net.fabricmc.loom.configuration.DependencyProvider;
|
||||||
|
import net.fabricmc.loom.configuration.accesswidener.AccessWidenerJarProcessor;
|
||||||
|
import net.fabricmc.loom.configuration.processors.JarProcessorManager;
|
||||||
|
import net.fabricmc.loom.configuration.processors.MinecraftProcessedProvider;
|
||||||
|
import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl;
|
||||||
|
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider;
|
||||||
|
import net.fabricmc.loom.util.Constants;
|
||||||
|
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.stitch.Command;
|
||||||
|
import net.fabricmc.stitch.commands.CommandProposeFieldNames;
|
||||||
|
import net.fabricmc.stitch.commands.tinyv2.CommandMergeTinyV2;
|
||||||
|
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;
|
||||||
|
|
||||||
|
private final Path mappingsDir;
|
||||||
|
private final Path mappingsStepsDir;
|
||||||
|
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;
|
||||||
|
private boolean hasUnpickDefinitions;
|
||||||
|
private UnpickMetadata unpickMetadata;
|
||||||
|
|
||||||
|
public MappingsProviderImpl(Project project) {
|
||||||
|
super(project);
|
||||||
|
mappingsDir = getExtension().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());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void provide(DependencyInfo dependency, Consumer<Runnable> postPopulationScheduler) throws Exception {
|
||||||
|
MinecraftProviderImpl minecraftProvider = getDependencyManager().getProvider(MinecraftProviderImpl.class);
|
||||||
|
|
||||||
|
getProject().getLogger().info(":setting up mappings (" + dependency.getDependency().getName() + " " + dependency.getResolvedVersion() + ")");
|
||||||
|
|
||||||
|
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" : "");
|
||||||
|
|
||||||
|
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(getExtension().getUserCache(), mappingsJar.getName().replace(".jar", "-" + jarClassifier + ".jar"));
|
||||||
|
|
||||||
|
if (!tinyMappings.exists() || isRefreshDeps()) {
|
||||||
|
storeMappings(getProject(), minecraftProvider, mappingsJar.toPath());
|
||||||
|
} else {
|
||||||
|
try (FileSystem fileSystem = FileSystems.newFileSystem(mappingsJar.toPath(), (ClassLoader) null)) {
|
||||||
|
extractUnpickDefinitions(fileSystem, unpickDefinitionsFile.toPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tinyMappingsJar.exists() || isRefreshDeps()) {
|
||||||
|
ZipUtil.pack(new ZipEntrySource[] {new FileSource("mappings/mappings.tiny", tinyMappings)}, tinyMappingsJar);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasUnpickDefinitions()) {
|
||||||
|
String notation = String.format("%s:%s:%s:constants",
|
||||||
|
dependency.getDependency().getGroup(),
|
||||||
|
dependency.getDependency().getName(),
|
||||||
|
dependency.getDependency().getVersion()
|
||||||
|
);
|
||||||
|
|
||||||
|
getProject().getDependencies().add(Constants.Configurations.MAPPING_CONSTANTS, notation);
|
||||||
|
populateUnpickClasspath();
|
||||||
|
}
|
||||||
|
|
||||||
|
addDependency(tinyMappingsJar, Constants.Configurations.MAPPINGS_FINAL);
|
||||||
|
|
||||||
|
LoomGradleExtension extension = getExtension();
|
||||||
|
|
||||||
|
if (extension.accessWidener != null) {
|
||||||
|
extension.addJarProcessor(new AccessWidenerJarProcessor(getProject()));
|
||||||
|
}
|
||||||
|
|
||||||
|
JarProcessorManager processorManager = new JarProcessorManager(extension.getJarProcessors());
|
||||||
|
extension.setJarProcessorManager(processorManager);
|
||||||
|
processorManager.setupProcessors();
|
||||||
|
|
||||||
|
if (processorManager.active()) {
|
||||||
|
mappedProvider = new MinecraftProcessedProvider(getProject(), processorManager);
|
||||||
|
getProject().getLogger().lifecycle("Using project based jar storage");
|
||||||
|
} else {
|
||||||
|
mappedProvider = new MinecraftMappedProvider(getProject());
|
||||||
|
}
|
||||||
|
|
||||||
|
mappedProvider.initFiles(minecraftProvider, this);
|
||||||
|
mappedProvider.provide(dependency, postPopulationScheduler);
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (baseMappingsAreV2()) {
|
||||||
|
// These are unmerged v2 mappings
|
||||||
|
mergeAndSaveMappings(project, yarnJar);
|
||||||
|
} else {
|
||||||
|
// These are merged v1 mappings
|
||||||
|
if (tinyMappings.exists()) {
|
||||||
|
tinyMappings.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
project.getLogger().lifecycle(":populating field names");
|
||||||
|
suggestFieldNames(minecraftProvider, baseTinyMappings, tinyMappings.toPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean baseMappingsAreV2() throws IOException {
|
||||||
|
try (BufferedReader reader = Files.newBufferedReader(baseTinyMappings)) {
|
||||||
|
TinyV2Factory.readMetadata(reader);
|
||||||
|
return true;
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// TODO: just check the mappings version when Parser supports V1 in readMetadata()
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private 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);
|
||||||
|
return true;
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void extractMappings(FileSystem jar, Path extractTo) throws IOException {
|
||||||
|
Files.copy(jar.getPath("mappings/mappings.tiny"), extractTo, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void extractUnpickDefinitions(FileSystem jar, Path extractTo) throws IOException {
|
||||||
|
Path unpickPath = jar.getPath("extras/definitions.unpick");
|
||||||
|
Path unpickMetadataPath = jar.getPath("extras/unpick.json");
|
||||||
|
|
||||||
|
if (!Files.exists(unpickPath) || !Files.exists(unpickMetadataPath)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Files.copy(unpickPath, extractTo, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
|
||||||
|
unpickMetadata = parseUnpickMetadata(unpickMetadataPath);
|
||||||
|
hasUnpickDefinitions = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private UnpickMetadata parseUnpickMetadata(Path input) throws IOException {
|
||||||
|
JsonObject jsonObject = LoomGradlePlugin.GSON.fromJson(Files.readString(input), JsonObject.class);
|
||||||
|
|
||||||
|
if (!jsonObject.has("version") || jsonObject.get("version").getAsInt() != 1) {
|
||||||
|
throw new UnsupportedOperationException("Unsupported unpick version");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UnpickMetadata(
|
||||||
|
jsonObject.get("unpickGroup").getAsString(),
|
||||||
|
jsonObject.get("unpickVersion").getAsString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateUnpickClasspath() {
|
||||||
|
String unpickCliName = "unpick-cli";
|
||||||
|
getProject().getDependencies().add(Constants.Configurations.UNPICK_CLASSPATH,
|
||||||
|
String.format("%s:%s:%s", unpickMetadata.unpickGroup, unpickCliName, unpickMetadata.unpickVersion)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void extractIntermediary(Path intermediaryJar, Path intermediaryTiny) throws IOException {
|
||||||
|
getProject().getLogger().info(":extracting " + intermediaryJar.getFileName());
|
||||||
|
|
||||||
|
try (FileSystem unmergedIntermediaryFs = FileSystems.newFileSystem(intermediaryJar, (ClassLoader) null)) {
|
||||||
|
extractMappings(unmergedIntermediaryFs, intermediaryTiny);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mergeAndSaveMappings(Project project, Path unmergedYarnJar) throws IOException {
|
||||||
|
Path unmergedYarn = Paths.get(mappingsStepsDir.toString(), "unmerged-yarn.tiny");
|
||||||
|
project.getLogger().info(":extracting " + unmergedYarnJar.getFileName());
|
||||||
|
|
||||||
|
try (FileSystem unmergedYarnJarFs = FileSystems.newFileSystem(unmergedYarnJar, (ClassLoader) null)) {
|
||||||
|
extractMappings(unmergedYarnJarFs, unmergedYarn);
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reorderMappings(Path oldMappings, Path newMappings, String... newOrder) {
|
||||||
|
Command command = new CommandReorderTinyV2();
|
||||||
|
String[] args = new String[2 + newOrder.length];
|
||||||
|
args[0] = oldMappings.toAbsolutePath().toString();
|
||||||
|
args[1] = newMappings.toAbsolutePath().toString();
|
||||||
|
System.arraycopy(newOrder, 0, args, 2, newOrder.length);
|
||||||
|
runCommand(command, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mergeMappings(Path intermediaryMappings, Path yarnMappings, Path newMergedMappings) {
|
||||||
|
try {
|
||||||
|
Command command = new CommandMergeTinyV2();
|
||||||
|
runCommand(command, intermediaryMappings.toAbsolutePath().toString(),
|
||||||
|
yarnMappings.toAbsolutePath().toString(),
|
||||||
|
newMergedMappings.toAbsolutePath().toString(),
|
||||||
|
"intermediary", "official");
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Could not merge mappings from " + intermediaryMappings.toString()
|
||||||
|
+ " with mappings from " + yarnMappings, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void suggestFieldNames(MinecraftProviderImpl minecraftProvider, Path oldMappings, Path newMappings) {
|
||||||
|
Command command = new CommandProposeFieldNames();
|
||||||
|
runCommand(command, minecraftProvider.getMergedJar().getAbsolutePath(),
|
||||||
|
oldMappings.toAbsolutePath().toString(),
|
||||||
|
newMappings.toAbsolutePath().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runCommand(Command command, String... args) {
|
||||||
|
try {
|
||||||
|
command.run(args);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initFiles() {
|
||||||
|
baseTinyMappings = mappingsDir.resolve(mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion + "-base");
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTargetConfig() {
|
||||||
|
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));
|
||||||
|
|
||||||
|
if (!Files.exists(intermediaryTiny) || (isRefreshDeps() && !hasRefreshed)) {
|
||||||
|
hasRefreshed = true;
|
||||||
|
|
||||||
|
// Download and extract intermediary
|
||||||
|
String encodedMinecraftVersion = UrlEscapers.urlFragmentEscaper().escape(minecraftVersion);
|
||||||
|
String intermediaryArtifactUrl = getExtension().getIntermediaryUrl().apply(encodedMinecraftVersion);
|
||||||
|
Path intermediaryJar = mappingsDir.resolve("v2-intermediary-" + minecraftVersion + ".jar");
|
||||||
|
DownloadUtil.downloadIfChanged(new URL(intermediaryArtifactUrl), intermediaryJar.toFile(), getProject().getLogger());
|
||||||
|
|
||||||
|
extractIntermediary(intermediaryJar, intermediaryTiny);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return intermediaryTiny;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMappingsKey() {
|
||||||
|
return mappingsName + "." + minecraftVersion.replace(' ', '_').replace('.', '_').replace('-', '_') + "." + mappingsVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getUnpickDefinitionsFile() {
|
||||||
|
return unpickDefinitionsFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasUnpickDefinitions() {
|
||||||
|
return hasUnpickDefinitions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File intermediaryTinyFile() {
|
||||||
|
try {
|
||||||
|
return getIntermediaryTiny().toFile();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Failed to get intermediary", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record UnpickMetadata(String unpickGroup, String unpickVersion) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.configuration.providers.mappings;
|
||||||
|
|
||||||
|
public interface MappingsSpec<L extends MappingLayer> {
|
||||||
|
L createLayer(MappingContext context);
|
||||||
|
}
|
|
@ -1,275 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
|
||||||
*
|
|
||||||
* Copyright (c) 2016, 2017, 2018 FabricMC
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package net.fabricmc.loom.configuration.providers.mappings;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.io.Writer;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import org.cadixdev.lorenz.MappingSet;
|
|
||||||
import org.cadixdev.lorenz.io.TextMappingsWriter;
|
|
||||||
import org.cadixdev.lorenz.io.proguard.ProGuardReader;
|
|
||||||
import org.cadixdev.lorenz.model.ClassMapping;
|
|
||||||
import org.cadixdev.lorenz.model.FieldMapping;
|
|
||||||
import org.cadixdev.lorenz.model.InnerClassMapping;
|
|
||||||
import org.cadixdev.lorenz.model.MethodMapping;
|
|
||||||
import org.cadixdev.lorenz.model.TopLevelClassMapping;
|
|
||||||
import org.gradle.api.Project;
|
|
||||||
import org.gradle.api.artifacts.Dependency;
|
|
||||||
import org.gradle.api.artifacts.SelfResolvingDependency;
|
|
||||||
import org.gradle.api.tasks.TaskDependency;
|
|
||||||
import org.zeroturnaround.zip.ByteSource;
|
|
||||||
import org.zeroturnaround.zip.ZipEntrySource;
|
|
||||||
import org.zeroturnaround.zip.ZipUtil;
|
|
||||||
|
|
||||||
import net.fabricmc.loom.LoomGradleExtension;
|
|
||||||
import net.fabricmc.loom.LoomGradlePlugin;
|
|
||||||
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta;
|
|
||||||
import net.fabricmc.loom.util.HashedDownloadUtil;
|
|
||||||
import net.fabricmc.lorenztiny.TinyMappingsReader;
|
|
||||||
import net.fabricmc.mapping.tree.TinyMappingFactory;
|
|
||||||
|
|
||||||
public class MojangMappingsDependency implements SelfResolvingDependency {
|
|
||||||
public static final String GROUP = "net.minecraft";
|
|
||||||
public static final String MODULE = "mappings";
|
|
||||||
// Keys in dependency manifest
|
|
||||||
private static final String MANIFEST_CLIENT_MAPPINGS = "client_mappings";
|
|
||||||
private static final String MANIFEST_SERVER_MAPPINGS = "server_mappings";
|
|
||||||
|
|
||||||
private final Project project;
|
|
||||||
private final LoomGradleExtension extension;
|
|
||||||
|
|
||||||
public MojangMappingsDependency(Project project, LoomGradleExtension extension) {
|
|
||||||
this.project = project;
|
|
||||||
this.extension = extension;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<File> resolve() {
|
|
||||||
Path mappingsDir = extension.getMappingsProvider().getMappingsDir();
|
|
||||||
Path mappingsFile = mappingsDir.resolve(String.format("%s.%s-%s.tiny", GROUP, MODULE, getVersion()));
|
|
||||||
Path clientMappings = mappingsDir.resolve(String.format("%s.%s-%s-client.map", GROUP, MODULE, getVersion()));
|
|
||||||
Path serverMappings = mappingsDir.resolve(String.format("%s.%s-%s-server.map", GROUP, MODULE, getVersion()));
|
|
||||||
|
|
||||||
if (!Files.exists(mappingsFile) || LoomGradlePlugin.refreshDeps) {
|
|
||||||
MappingSet mappingSet;
|
|
||||||
|
|
||||||
try {
|
|
||||||
mappingSet = getMappingsSet(clientMappings, serverMappings);
|
|
||||||
|
|
||||||
try (Writer writer = new StringWriter()) {
|
|
||||||
new TinyWriter(writer, "intermediary", "named").write(mappingSet);
|
|
||||||
Files.deleteIfExists(mappingsFile);
|
|
||||||
|
|
||||||
ZipUtil.pack(new ZipEntrySource[] {
|
|
||||||
new ByteSource("mappings/mappings.tiny", writer.toString().getBytes(StandardCharsets.UTF_8))
|
|
||||||
}, mappingsFile.toFile());
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("Failed to resolve Mojang mappings", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try (BufferedReader clientBufferedReader = Files.newBufferedReader(clientMappings, StandardCharsets.UTF_8)) {
|
|
||||||
project.getLogger().warn("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
|
||||||
project.getLogger().warn("Using of the official minecraft mappings is at your own risk!");
|
|
||||||
project.getLogger().warn("Please make sure to read and understand the following license:");
|
|
||||||
project.getLogger().warn("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
|
||||||
String line;
|
|
||||||
|
|
||||||
while ((line = clientBufferedReader.readLine()).startsWith("#")) {
|
|
||||||
project.getLogger().warn(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
project.getLogger().warn("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("Failed to read client mappings", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Collections.singleton(mappingsFile.toFile());
|
|
||||||
}
|
|
||||||
|
|
||||||
private MappingSet getMappingsSet(Path clientMappings, Path serverMappings) throws IOException {
|
|
||||||
MinecraftVersionMeta versionInfo = extension.getMinecraftProvider().getVersionInfo();
|
|
||||||
|
|
||||||
if (versionInfo.download(MANIFEST_CLIENT_MAPPINGS) == null) {
|
|
||||||
throw new RuntimeException("Failed to find official mojang mappings for " + getVersion());
|
|
||||||
}
|
|
||||||
|
|
||||||
MinecraftVersionMeta.Download clientMappingsDownload = versionInfo.download(MANIFEST_CLIENT_MAPPINGS);
|
|
||||||
MinecraftVersionMeta.Download serverMappingsDownload = versionInfo.download(MANIFEST_CLIENT_MAPPINGS);
|
|
||||||
|
|
||||||
HashedDownloadUtil.downloadIfInvalid(new URL(clientMappingsDownload.url()), clientMappings.toFile(), clientMappingsDownload.sha1(), project.getLogger(), false);
|
|
||||||
HashedDownloadUtil.downloadIfInvalid(new URL(serverMappingsDownload.url()), serverMappings.toFile(), clientMappingsDownload.sha1(), project.getLogger(), false);
|
|
||||||
|
|
||||||
MappingSet mappings = MappingSet.create();
|
|
||||||
|
|
||||||
try (BufferedReader clientBufferedReader = Files.newBufferedReader(clientMappings, StandardCharsets.UTF_8);
|
|
||||||
BufferedReader serverBufferedReader = Files.newBufferedReader(serverMappings, StandardCharsets.UTF_8)) {
|
|
||||||
try (ProGuardReader proGuardReaderClient = new ProGuardReader(clientBufferedReader);
|
|
||||||
ProGuardReader proGuardReaderServer = new ProGuardReader(serverBufferedReader)) {
|
|
||||||
proGuardReaderClient.read(mappings);
|
|
||||||
proGuardReaderServer.read(mappings);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MappingSet officialToNamed = mappings.reverse();
|
|
||||||
MappingSet intermediaryToOfficial;
|
|
||||||
|
|
||||||
try (BufferedReader reader = Files.newBufferedReader(extension.getMappingsProvider().getIntermediaryTiny(), StandardCharsets.UTF_8)) {
|
|
||||||
intermediaryToOfficial = new TinyMappingsReader(TinyMappingFactory.loadWithDetection(reader), "intermediary", "official").read();
|
|
||||||
}
|
|
||||||
|
|
||||||
MappingSet intermediaryToMojang = MappingSet.create();
|
|
||||||
|
|
||||||
// Merging. Don't use MappingSet#merge
|
|
||||||
iterateClasses(intermediaryToOfficial, inputMappings -> {
|
|
||||||
officialToNamed.getClassMapping(inputMappings.getFullDeobfuscatedName())
|
|
||||||
.ifPresent(namedClass -> {
|
|
||||||
ClassMapping<?, ?> mojangClassMapping = intermediaryToMojang.getOrCreateClassMapping(inputMappings.getFullObfuscatedName())
|
|
||||||
.setDeobfuscatedName(namedClass.getFullDeobfuscatedName());
|
|
||||||
|
|
||||||
for (FieldMapping fieldMapping : inputMappings .getFieldMappings()) {
|
|
||||||
namedClass.getFieldMapping(fieldMapping.getDeobfuscatedName())
|
|
||||||
.ifPresent(namedField -> {
|
|
||||||
mojangClassMapping.getOrCreateFieldMapping(fieldMapping.getSignature())
|
|
||||||
.setDeobfuscatedName(namedField.getDeobfuscatedName());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (MethodMapping methodMapping : inputMappings .getMethodMappings()) {
|
|
||||||
namedClass.getMethodMapping(methodMapping.getDeobfuscatedSignature())
|
|
||||||
.ifPresent(namedMethod -> {
|
|
||||||
mojangClassMapping.getOrCreateMethodMapping(methodMapping.getSignature())
|
|
||||||
.setDeobfuscatedName(namedMethod.getDeobfuscatedName());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return intermediaryToMojang;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<File> resolve(boolean transitive) {
|
|
||||||
return resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TaskDependency getBuildDependencies() {
|
|
||||||
return task -> Collections.emptySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getGroup() {
|
|
||||||
return GROUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return MODULE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getVersion() {
|
|
||||||
return extension.getMinecraftProvider().getMinecraftVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean contentEquals(Dependency dependency) {
|
|
||||||
if (dependency instanceof MojangMappingsDependency mojangMappingsDependency) {
|
|
||||||
return mojangMappingsDependency.extension.getMinecraftProvider().getMinecraftVersion().equals(getVersion());
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Dependency copy() {
|
|
||||||
return new MojangMappingsDependency(project, extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getReason() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void because(String s) {
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void iterateClasses(MappingSet mappings, Consumer<ClassMapping<?, ?>> consumer) {
|
|
||||||
for (TopLevelClassMapping classMapping : mappings.getTopLevelClassMappings()) {
|
|
||||||
iterateClass(classMapping, consumer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void iterateClass(ClassMapping<?, ?> classMapping, Consumer<ClassMapping<?, ?>> consumer) {
|
|
||||||
consumer.accept(classMapping);
|
|
||||||
|
|
||||||
for (InnerClassMapping innerClassMapping : classMapping.getInnerClassMappings()) {
|
|
||||||
iterateClass(innerClassMapping, consumer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class TinyWriter extends TextMappingsWriter {
|
|
||||||
private final String namespaceFrom;
|
|
||||||
private final String namespaceTo;
|
|
||||||
|
|
||||||
protected TinyWriter(Writer writer, String namespaceFrom, String namespaceTo) {
|
|
||||||
super(writer);
|
|
||||||
this.namespaceFrom = namespaceFrom;
|
|
||||||
this.namespaceTo = namespaceTo;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(MappingSet mappings) {
|
|
||||||
writer.println("tiny\t2\t0\t" + namespaceFrom + "\t" + namespaceTo);
|
|
||||||
|
|
||||||
iterateClasses(mappings, classMapping -> {
|
|
||||||
writer.println("c\t" + classMapping.getFullObfuscatedName() + "\t" + classMapping.getFullDeobfuscatedName());
|
|
||||||
|
|
||||||
for (FieldMapping fieldMapping : classMapping.getFieldMappings()) {
|
|
||||||
fieldMapping.getType().ifPresent(fieldType -> {
|
|
||||||
writer.println("\tf\t" + fieldType + "\t" + fieldMapping.getObfuscatedName() + "\t" + fieldMapping.getDeobfuscatedName());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (MethodMapping methodMapping : classMapping.getMethodMappings()) {
|
|
||||||
writer.println("\tm\t" + methodMapping.getSignature().getDescriptor() + "\t" + methodMapping.getObfuscatedName() + "\t" + methodMapping.getDeobfuscatedName());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.configuration.providers.mappings.intermediary;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.MappingLayer;
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.MappingNamespace;
|
||||||
|
import net.fabricmc.mappingio.MappingVisitor;
|
||||||
|
import net.fabricmc.mappingio.adapter.MappingNsCompleter;
|
||||||
|
import net.fabricmc.mappingio.format.Tiny2Reader;
|
||||||
|
|
||||||
|
public record IntermediaryMappingLayer(File tinyFile) implements MappingLayer {
|
||||||
|
@Override
|
||||||
|
public MappingNamespace getSourceNamespace() {
|
||||||
|
return MappingNamespace.OFFICIAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(MappingVisitor mappingVisitor) throws IOException {
|
||||||
|
// Populate named with intermediary and add Add a "named" namespace
|
||||||
|
MappingNsCompleter nsCompleter = new MappingNsCompleter(mappingVisitor, Collections.singletonMap(MappingNamespace.NAMED.stringValue(), MappingNamespace.INTERMEDIARY.stringValue()), true);
|
||||||
|
|
||||||
|
try (BufferedReader reader = Files.newBufferedReader(tinyFile().toPath(), StandardCharsets.UTF_8)) {
|
||||||
|
Tiny2Reader.read(reader, nsCompleter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.configuration.providers.mappings.intermediary;
|
||||||
|
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.MappingContext;
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.MappingsSpec;
|
||||||
|
|
||||||
|
public record IntermediaryMappingsSpec() implements MappingsSpec<IntermediaryMappingLayer> {
|
||||||
|
@Override
|
||||||
|
public IntermediaryMappingLayer createLayer(MappingContext context) {
|
||||||
|
return new IntermediaryMappingLayer(context.mappingsProvider().intermediaryTinyFile());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.configuration.providers.mappings.mojmap;
|
||||||
|
|
||||||
|
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.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.gradle.api.logging.Logger;
|
||||||
|
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.MappingLayer;
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.MappingNamespace;
|
||||||
|
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta;
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingLayer;
|
||||||
|
import net.fabricmc.loom.util.HashedDownloadUtil;
|
||||||
|
import net.fabricmc.mappingio.MappingVisitor;
|
||||||
|
import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch;
|
||||||
|
import net.fabricmc.mappingio.format.ProGuardReader;
|
||||||
|
|
||||||
|
public record MojangMappingLayer(MinecraftVersionMeta.Download clientDownload,
|
||||||
|
MinecraftVersionMeta.Download serverDownload,
|
||||||
|
File workingDir,
|
||||||
|
Logger logger) implements MappingLayer {
|
||||||
|
@Override
|
||||||
|
public void visit(MappingVisitor mappingVisitor) throws IOException {
|
||||||
|
var clientMappings = new File(workingDir(), "client.txt");
|
||||||
|
var serverMappings = new File(workingDir(), "server.txt");
|
||||||
|
|
||||||
|
download(clientMappings, serverMappings);
|
||||||
|
|
||||||
|
printMappingsLicense(clientMappings.toPath());
|
||||||
|
|
||||||
|
// Make official the source namespace
|
||||||
|
MappingSourceNsSwitch nsSwitch = new MappingSourceNsSwitch(mappingVisitor, MappingNamespace.OFFICIAL.stringValue());
|
||||||
|
|
||||||
|
try (BufferedReader clientBufferedReader = Files.newBufferedReader(clientMappings.toPath(), StandardCharsets.UTF_8);
|
||||||
|
BufferedReader serverBufferedReader = Files.newBufferedReader(serverMappings.toPath(), StandardCharsets.UTF_8)) {
|
||||||
|
ProGuardReader.read(clientBufferedReader, MappingNamespace.NAMED.stringValue(), MappingNamespace.OFFICIAL.stringValue(), nsSwitch);
|
||||||
|
ProGuardReader.read(serverBufferedReader, MappingNamespace.NAMED.stringValue(), MappingNamespace.OFFICIAL.stringValue(), nsSwitch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void download(File clientMappings, File serverMappings) throws IOException {
|
||||||
|
HashedDownloadUtil.downloadIfInvalid(new URL(clientDownload().url()), clientMappings, clientDownload().sha1(), logger(), false);
|
||||||
|
HashedDownloadUtil.downloadIfInvalid(new URL(serverDownload().url()), serverMappings, serverDownload().sha1(), logger(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printMappingsLicense(Path clientMappings) {
|
||||||
|
try (BufferedReader clientBufferedReader = Files.newBufferedReader(clientMappings, StandardCharsets.UTF_8)) {
|
||||||
|
logger().warn("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
||||||
|
logger().warn("Using of the official minecraft mappings is at your own risk!");
|
||||||
|
logger().warn("Please make sure to read and understand the following license:");
|
||||||
|
logger().warn("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
||||||
|
String line;
|
||||||
|
|
||||||
|
while ((line = clientBufferedReader.readLine()).startsWith("#")) {
|
||||||
|
logger().warn(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger().warn("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Failed to read client mappings", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappingNamespace getSourceNamespace() {
|
||||||
|
return MappingNamespace.OFFICIAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Class<? extends MappingLayer>> dependsOn() {
|
||||||
|
return List.of(IntermediaryMappingLayer.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.configuration.providers.mappings.mojmap;
|
||||||
|
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.MappingContext;
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.MappingsSpec;
|
||||||
|
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta;
|
||||||
|
|
||||||
|
public record MojangMappingsSpec() implements MappingsSpec<MojangMappingLayer> {
|
||||||
|
// Keys in dependency manifest
|
||||||
|
private static final String MANIFEST_CLIENT_MAPPINGS = "client_mappings";
|
||||||
|
private static final String MANIFEST_SERVER_MAPPINGS = "server_mappings";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MojangMappingLayer createLayer(MappingContext context) {
|
||||||
|
MinecraftVersionMeta versionInfo = context.minecraftProvider().getVersionInfo();
|
||||||
|
|
||||||
|
if (versionInfo.download(MANIFEST_CLIENT_MAPPINGS) == null) {
|
||||||
|
throw new RuntimeException("Failed to find official mojang mappings for " + context.minecraftVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MojangMappingLayer(
|
||||||
|
versionInfo.download(MANIFEST_CLIENT_MAPPINGS),
|
||||||
|
versionInfo.download(MANIFEST_SERVER_MAPPINGS),
|
||||||
|
context.workingDirectory("mojang"),
|
||||||
|
context.getLogger()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.configuration.providers.mappings.parchment;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
|
import net.fabricmc.loom.LoomGradlePlugin;
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.MappingLayer;
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.MappingNamespace;
|
||||||
|
import net.fabricmc.mappingio.MappingVisitor;
|
||||||
|
|
||||||
|
public record ParchmentMappingLayer(File parchmentFile, boolean removePrefix) implements MappingLayer {
|
||||||
|
private static final String PARCHMENT_DATA_FILE_NAME = "parchment.json";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(MappingVisitor mappingVisitor) throws IOException {
|
||||||
|
ParchmentTreeV1 parchmentData = getParchmentData();
|
||||||
|
|
||||||
|
if (removePrefix()) {
|
||||||
|
mappingVisitor = new ParchmentPrefixStripingMappingVisitor(mappingVisitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
parchmentData.visit(mappingVisitor, MappingNamespace.NAMED.stringValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private ParchmentTreeV1 getParchmentData() throws IOException {
|
||||||
|
try (var zipFile = new ZipFile(parchmentFile())) {
|
||||||
|
ZipEntry zipFileEntry = zipFile.getEntry(PARCHMENT_DATA_FILE_NAME);
|
||||||
|
Objects.requireNonNull(zipFileEntry, "Could not find %s in parchment data file".formatted(PARCHMENT_DATA_FILE_NAME));
|
||||||
|
|
||||||
|
try (var reader = new InputStreamReader(zipFile.getInputStream(zipFileEntry))) {
|
||||||
|
return LoomGradlePlugin.OBJECT_MAPPER.readValue(reader, ParchmentTreeV1.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.configuration.providers.mappings.parchment;
|
||||||
|
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.MappingContext;
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.MappingsSpec;
|
||||||
|
|
||||||
|
public record ParchmentMappingsSpec(String mavenNotation, boolean removePrefix) implements MappingsSpec<ParchmentMappingLayer> {
|
||||||
|
@Override
|
||||||
|
public ParchmentMappingLayer createLayer(MappingContext context) {
|
||||||
|
return new ParchmentMappingLayer(context.mavenFile(mavenNotation()), removePrefix());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.configuration.providers.mappings.parchment;
|
||||||
|
|
||||||
|
public class ParchmentMappingsSpecBuilder {
|
||||||
|
private final String mavenNotation;
|
||||||
|
|
||||||
|
private boolean removePrefix;
|
||||||
|
|
||||||
|
private ParchmentMappingsSpecBuilder(String mavenNotation) {
|
||||||
|
this.mavenNotation = mavenNotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ParchmentMappingsSpecBuilder builder(String depNotation) {
|
||||||
|
return new ParchmentMappingsSpecBuilder(depNotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParchmentMappingsSpecBuilder setRemovePrefix(boolean removePrefix) {
|
||||||
|
this.removePrefix = removePrefix;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParchmentMappingsSpec build() {
|
||||||
|
return new ParchmentMappingsSpec(mavenNotation, removePrefix);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.configuration.providers.mappings.parchment;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import net.fabricmc.mappingio.MappingVisitor;
|
||||||
|
import net.fabricmc.mappingio.adapter.ForwardingMappingVisitor;
|
||||||
|
|
||||||
|
public final class ParchmentPrefixStripingMappingVisitor extends ForwardingMappingVisitor {
|
||||||
|
protected ParchmentPrefixStripingMappingVisitor(MappingVisitor next) {
|
||||||
|
super(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean visitMethodArg(int argPosition, int lvIndex, String srcName) {
|
||||||
|
return super.visitMethodArg(argPosition, lvIndex, stripMethodArg(srcName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String stripMethodArg(String arg) {
|
||||||
|
if (arg.length() > 1 && arg.startsWith("p") && Character.isUpperCase(arg.charAt(1))) {
|
||||||
|
String a2 = arg.substring(1); // Remove p
|
||||||
|
return a2.substring(0, 1).toLowerCase(Locale.ROOT) + a2.substring(1); // Make first char lowercase
|
||||||
|
}
|
||||||
|
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,165 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.configuration.providers.mappings.parchment;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import net.fabricmc.mappingio.MappedElementKind;
|
||||||
|
import net.fabricmc.mappingio.MappingVisitor;
|
||||||
|
|
||||||
|
public record ParchmentTreeV1(
|
||||||
|
String version,
|
||||||
|
@Nullable
|
||||||
|
List<Class> classes,
|
||||||
|
@Nullable
|
||||||
|
List<Package> packages
|
||||||
|
) {
|
||||||
|
public void visit(MappingVisitor visitor, String srcNamespace) {
|
||||||
|
while (true) {
|
||||||
|
if (visitor.visitHeader()) {
|
||||||
|
visitor.visitNamespaces(srcNamespace, Collections.emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (visitor.visitContent()) {
|
||||||
|
if (classes() != null) {
|
||||||
|
for (Class c : classes()) {
|
||||||
|
c.visit(visitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (visitor.visitEnd()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record Class(
|
||||||
|
String name,
|
||||||
|
@Nullable
|
||||||
|
List<Field> fields,
|
||||||
|
@Nullable
|
||||||
|
List<Method> methods,
|
||||||
|
@Nullable
|
||||||
|
List<String> javadoc
|
||||||
|
) {
|
||||||
|
public void visit(MappingVisitor visitor) {
|
||||||
|
if (visitor.visitClass(name())) {
|
||||||
|
if (!visitor.visitElementContent(MappedElementKind.CLASS)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields() != null) {
|
||||||
|
for (Field field : fields()) {
|
||||||
|
field.visit(visitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (methods() != null) {
|
||||||
|
for (Method method : methods()) {
|
||||||
|
method.visit(visitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (javadoc() != null) {
|
||||||
|
visitor.visitComment(MappedElementKind.CLASS, String.join("\n", javadoc()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record Field(
|
||||||
|
String name,
|
||||||
|
String descriptor,
|
||||||
|
@Nullable
|
||||||
|
List<String> javadoc
|
||||||
|
) {
|
||||||
|
public void visit(MappingVisitor visitor) {
|
||||||
|
if (visitor.visitField(name, descriptor)) {
|
||||||
|
if (!visitor.visitElementContent(MappedElementKind.FIELD)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (javadoc() != null) {
|
||||||
|
visitor.visitComment(MappedElementKind.FIELD, String.join("\n", javadoc()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record Method(
|
||||||
|
String name,
|
||||||
|
String descriptor,
|
||||||
|
@Nullable
|
||||||
|
List<Parameter> parameters,
|
||||||
|
@Nullable
|
||||||
|
List<String> javadoc
|
||||||
|
) {
|
||||||
|
public void visit(MappingVisitor visitor) {
|
||||||
|
if (visitor.visitMethod(name, descriptor)) {
|
||||||
|
if (!visitor.visitElementContent(MappedElementKind.METHOD)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parameters() != null) {
|
||||||
|
for (Parameter parameter : parameters()) {
|
||||||
|
parameter.visit(visitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (javadoc() != null) {
|
||||||
|
visitor.visitComment(MappedElementKind.METHOD, String.join("\n", javadoc()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record Parameter(
|
||||||
|
int index,
|
||||||
|
String name,
|
||||||
|
@Nullable
|
||||||
|
String javadoc
|
||||||
|
) {
|
||||||
|
public void visit(MappingVisitor visitor) {
|
||||||
|
if (visitor.visitMethodArg(index, index, name)) {
|
||||||
|
if (!visitor.visitElementContent(MappedElementKind.METHOD_ARG)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (javadoc() != null) {
|
||||||
|
visitor.visitComment(MappedElementKind.METHOD_ARG, javadoc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record Package(
|
||||||
|
String name,
|
||||||
|
List<String> javadoc
|
||||||
|
) { }
|
||||||
|
}
|
|
@ -29,13 +29,13 @@ import java.io.File;
|
||||||
import org.gradle.api.Project;
|
import org.gradle.api.Project;
|
||||||
|
|
||||||
import net.fabricmc.loom.LoomGradleExtension;
|
import net.fabricmc.loom.LoomGradleExtension;
|
||||||
import net.fabricmc.loom.configuration.providers.MinecraftProvider;
|
import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl;
|
||||||
import net.fabricmc.loom.util.Constants;
|
import net.fabricmc.loom.util.Constants;
|
||||||
|
|
||||||
public class MinecraftLibraryProvider {
|
public class MinecraftLibraryProvider {
|
||||||
public File MINECRAFT_LIBS;
|
public File MINECRAFT_LIBS;
|
||||||
|
|
||||||
public void provide(MinecraftProvider minecraftProvider, Project project) {
|
public void provide(MinecraftProviderImpl minecraftProvider, Project project) {
|
||||||
MinecraftVersionMeta versionInfo = minecraftProvider.getVersionInfo();
|
MinecraftVersionMeta versionInfo = minecraftProvider.getVersionInfo();
|
||||||
|
|
||||||
initFiles(project, minecraftProvider);
|
initFiles(project, minecraftProvider);
|
||||||
|
@ -47,7 +47,7 @@ public class MinecraftLibraryProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initFiles(Project project, MinecraftProvider minecraftProvider) {
|
private void initFiles(Project project, MinecraftProviderImpl minecraftProvider) {
|
||||||
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
||||||
MINECRAFT_LIBS = new File(extension.getUserCache(), "libraries");
|
MINECRAFT_LIBS = new File(extension.getUserCache(), "libraries");
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,8 @@ import com.google.common.collect.ImmutableMap;
|
||||||
import org.gradle.api.Project;
|
import org.gradle.api.Project;
|
||||||
|
|
||||||
import net.fabricmc.loom.configuration.DependencyProvider;
|
import net.fabricmc.loom.configuration.DependencyProvider;
|
||||||
import net.fabricmc.loom.configuration.providers.MinecraftProvider;
|
import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl;
|
||||||
import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider;
|
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
|
||||||
import net.fabricmc.loom.util.Constants;
|
import net.fabricmc.loom.util.Constants;
|
||||||
import net.fabricmc.loom.util.TinyRemapperMappingsHelper;
|
import net.fabricmc.loom.util.TinyRemapperMappingsHelper;
|
||||||
import net.fabricmc.tinyremapper.OutputConsumerPath;
|
import net.fabricmc.tinyremapper.OutputConsumerPath;
|
||||||
|
@ -53,7 +53,7 @@ public class MinecraftMappedProvider extends DependencyProvider {
|
||||||
private File minecraftMappedJar;
|
private File minecraftMappedJar;
|
||||||
private File minecraftIntermediaryJar;
|
private File minecraftIntermediaryJar;
|
||||||
|
|
||||||
private MinecraftProvider minecraftProvider;
|
private MinecraftProviderImpl minecraftProvider;
|
||||||
|
|
||||||
public MinecraftMappedProvider(Project project) {
|
public MinecraftMappedProvider(Project project) {
|
||||||
super(project);
|
super(project);
|
||||||
|
@ -101,7 +101,7 @@ public class MinecraftMappedProvider extends DependencyProvider {
|
||||||
private void mapMinecraftJar() throws IOException {
|
private void mapMinecraftJar() throws IOException {
|
||||||
String fromM = "official";
|
String fromM = "official";
|
||||||
|
|
||||||
MappingsProvider mappingsProvider = getExtension().getMappingsProvider();
|
MappingsProviderImpl mappingsProvider = getExtension().getMappingsProvider();
|
||||||
|
|
||||||
Path input = minecraftProvider.getMergedJar().toPath();
|
Path input = minecraftProvider.getMergedJar().toPath();
|
||||||
Path outputMapped = minecraftMappedJar.toPath();
|
Path outputMapped = minecraftMappedJar.toPath();
|
||||||
|
@ -148,7 +148,7 @@ public class MinecraftMappedProvider extends DependencyProvider {
|
||||||
getProject().getDependencies().module("net.minecraft:minecraft:" + getJarVersionString("mapped")));
|
getProject().getDependencies().module("net.minecraft:minecraft:" + getJarVersionString("mapped")));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initFiles(MinecraftProvider minecraftProvider, MappingsProvider mappingsProvider) {
|
public void initFiles(MinecraftProviderImpl minecraftProvider, MappingsProviderImpl mappingsProvider) {
|
||||||
this.minecraftProvider = minecraftProvider;
|
this.minecraftProvider = minecraftProvider;
|
||||||
minecraftIntermediaryJar = new File(getExtension().getUserCache(), "minecraft-" + getJarVersionString("intermediary") + ".jar");
|
minecraftIntermediaryJar = new File(getExtension().getUserCache(), "minecraft-" + getJarVersionString("intermediary") + ".jar");
|
||||||
minecraftMappedJar = new File(getJarDirectory(getExtension().getUserCache(), "mapped"), "minecraft-" + getJarVersionString("mapped") + ".jar");
|
minecraftMappedJar = new File(getJarDirectory(getExtension().getUserCache(), "mapped"), "minecraft-" + getJarVersionString("mapped") + ".jar");
|
||||||
|
@ -159,7 +159,7 @@ public class MinecraftMappedProvider extends DependencyProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getJarVersionString(String type) {
|
protected String getJarVersionString(String type) {
|
||||||
return String.format("%s-%s-%s-%s", minecraftProvider.getMinecraftVersion(), type, getExtension().getMappingsProvider().mappingsName, getExtension().getMappingsProvider().mappingsVersion);
|
return String.format("%s-%s-%s-%s", minecraftProvider.minecraftVersion(), type, getExtension().getMappingsProvider().mappingsName, getExtension().getMappingsProvider().mappingsVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getIntermediaryJar() {
|
public File getIntermediaryJar() {
|
||||||
|
|
|
@ -41,14 +41,14 @@ import org.gradle.api.Project;
|
||||||
|
|
||||||
import net.fabricmc.loom.LoomGradleExtension;
|
import net.fabricmc.loom.LoomGradleExtension;
|
||||||
import net.fabricmc.loom.LoomGradlePlugin;
|
import net.fabricmc.loom.LoomGradlePlugin;
|
||||||
import net.fabricmc.loom.configuration.providers.MinecraftProvider;
|
import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl;
|
||||||
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta;
|
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta;
|
||||||
import net.fabricmc.loom.util.Constants;
|
import net.fabricmc.loom.util.Constants;
|
||||||
import net.fabricmc.loom.util.HashedDownloadUtil;
|
import net.fabricmc.loom.util.HashedDownloadUtil;
|
||||||
import net.fabricmc.loom.util.gradle.ProgressLogger;
|
import net.fabricmc.loom.util.gradle.ProgressLogger;
|
||||||
|
|
||||||
public class MinecraftAssetsProvider {
|
public class MinecraftAssetsProvider {
|
||||||
public static void provide(MinecraftProvider minecraftProvider, Project project) throws IOException {
|
public static void provide(MinecraftProviderImpl minecraftProvider, Project project) throws IOException {
|
||||||
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
||||||
boolean offline = project.getGradle().getStartParameter().isOffline();
|
boolean offline = project.getGradle().getStartParameter().isOffline();
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ public class MinecraftAssetsProvider {
|
||||||
assets.mkdirs();
|
assets.mkdirs();
|
||||||
}
|
}
|
||||||
|
|
||||||
File assetsInfo = new File(assets, "indexes" + File.separator + assetIndex.fabricId(minecraftProvider.getMinecraftVersion()) + ".json");
|
File assetsInfo = new File(assets, "indexes" + File.separator + assetIndex.fabricId(minecraftProvider.minecraftVersion()) + ".json");
|
||||||
|
|
||||||
project.getLogger().info(":downloading asset index");
|
project.getLogger().info(":downloading asset index");
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ import org.gradle.api.tasks.TaskAction;
|
||||||
import net.fabricmc.loom.LoomGradleExtension;
|
import net.fabricmc.loom.LoomGradleExtension;
|
||||||
import net.fabricmc.loom.api.decompilers.DecompilationMetadata;
|
import net.fabricmc.loom.api.decompilers.DecompilationMetadata;
|
||||||
import net.fabricmc.loom.api.decompilers.LoomDecompiler;
|
import net.fabricmc.loom.api.decompilers.LoomDecompiler;
|
||||||
import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider;
|
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
|
||||||
import net.fabricmc.loom.decompilers.LineNumberRemapper;
|
import net.fabricmc.loom.decompilers.LineNumberRemapper;
|
||||||
import net.fabricmc.loom.util.Constants;
|
import net.fabricmc.loom.util.Constants;
|
||||||
import net.fabricmc.loom.util.gradle.ProgressLogger;
|
import net.fabricmc.loom.util.gradle.ProgressLogger;
|
||||||
|
@ -102,7 +102,7 @@ public class GenerateSourcesTask extends AbstractLoomTask {
|
||||||
|
|
||||||
private File getMappedJarFileWithSuffix(String suffix) {
|
private File getMappedJarFileWithSuffix(String suffix) {
|
||||||
LoomGradleExtension extension = getProject().getExtensions().getByType(LoomGradleExtension.class);
|
LoomGradleExtension extension = getProject().getExtensions().getByType(LoomGradleExtension.class);
|
||||||
MappingsProvider mappingsProvider = extension.getMappingsProvider();
|
MappingsProviderImpl mappingsProvider = extension.getMappingsProvider();
|
||||||
File mappedJar = mappingsProvider.mappedProvider.getMappedJar();
|
File mappedJar = mappingsProvider.mappedProvider.getMappedJar();
|
||||||
String path = mappedJar.getAbsolutePath();
|
String path = mappedJar.getAbsolutePath();
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ import org.gradle.api.tasks.TaskContainer;
|
||||||
import net.fabricmc.loom.LoomGradleExtension;
|
import net.fabricmc.loom.LoomGradleExtension;
|
||||||
import net.fabricmc.loom.api.decompilers.LoomDecompiler;
|
import net.fabricmc.loom.api.decompilers.LoomDecompiler;
|
||||||
import net.fabricmc.loom.configuration.ide.RunConfigSettings;
|
import net.fabricmc.loom.configuration.ide.RunConfigSettings;
|
||||||
import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider;
|
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
|
||||||
import net.fabricmc.loom.decompilers.fernflower.FabricFernFlowerDecompiler;
|
import net.fabricmc.loom.decompilers.fernflower.FabricFernFlowerDecompiler;
|
||||||
|
|
||||||
public final class LoomTasks {
|
public final class LoomTasks {
|
||||||
|
@ -113,7 +113,7 @@ public final class LoomTasks {
|
||||||
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
||||||
|
|
||||||
project.afterEvaluate(p -> {
|
project.afterEvaluate(p -> {
|
||||||
MappingsProvider mappingsProvider = extension.getMappingsProvider();
|
MappingsProviderImpl mappingsProvider = extension.getMappingsProvider();
|
||||||
File inputJar = mappingsProvider.mappedProvider.getMappedJar();
|
File inputJar = mappingsProvider.mappedProvider.getMappedJar();
|
||||||
|
|
||||||
if (mappingsProvider.hasUnpickDefinitions()) {
|
if (mappingsProvider.hasUnpickDefinitions()) {
|
||||||
|
|
|
@ -49,9 +49,10 @@ import org.gradle.api.tasks.TaskAction;
|
||||||
import org.gradle.api.tasks.options.Option;
|
import org.gradle.api.tasks.options.Option;
|
||||||
|
|
||||||
import net.fabricmc.loom.LoomGradleExtension;
|
import net.fabricmc.loom.LoomGradleExtension;
|
||||||
import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider;
|
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
|
||||||
import net.fabricmc.loom.configuration.providers.mappings.MojangMappingsDependency;
|
|
||||||
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider;
|
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftMappedProvider;
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilder;
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsDependency;
|
||||||
import net.fabricmc.loom.util.SourceRemapper;
|
import net.fabricmc.loom.util.SourceRemapper;
|
||||||
import net.fabricmc.lorenztiny.TinyMappingsJoiner;
|
import net.fabricmc.lorenztiny.TinyMappingsJoiner;
|
||||||
import net.fabricmc.mapping.tree.TinyMappingFactory;
|
import net.fabricmc.mapping.tree.TinyMappingFactory;
|
||||||
|
@ -96,7 +97,7 @@ public class MigrateMappingsTask extends AbstractLoomTask {
|
||||||
Files.createDirectories(outputDir);
|
Files.createDirectories(outputDir);
|
||||||
|
|
||||||
File mappings = loadMappings();
|
File mappings = loadMappings();
|
||||||
MappingsProvider mappingsProvider = extension.getMappingsProvider();
|
MappingsProviderImpl mappingsProvider = extension.getMappingsProvider();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
TinyTree currentMappings = mappingsProvider.getMappings();
|
TinyTree currentMappings = mappingsProvider.getMappings();
|
||||||
|
@ -118,12 +119,13 @@ public class MigrateMappingsTask extends AbstractLoomTask {
|
||||||
Set<File> files;
|
Set<File> files;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (mappings.startsWith(MojangMappingsDependency.GROUP + ':' + MojangMappingsDependency.MODULE + ':') || mappings.startsWith("net.mojang.minecraft:mappings:")) {
|
if (mappings.startsWith("net.minecraft:mappings:") || mappings.startsWith("net.mojang.minecraft:mappings:")) {
|
||||||
if (!mappings.endsWith(":" + project.getExtensions().getByType(LoomGradleExtension.class).getMinecraftProvider().getMinecraftVersion())) {
|
if (!mappings.endsWith(":" + project.getExtensions().getByType(LoomGradleExtension.class).getMinecraftProvider().minecraftVersion())) {
|
||||||
throw new UnsupportedOperationException("Migrating Mojang mappings is currently only supported for the specified minecraft version");
|
throw new UnsupportedOperationException("Migrating Mojang mappings is currently only supported for the specified minecraft version");
|
||||||
}
|
}
|
||||||
|
|
||||||
files = new MojangMappingsDependency(project, getExtension()).resolve();
|
LayeredMappingsDependency dep = (LayeredMappingsDependency) getExtension().layered(LayeredMappingSpecBuilder::officalMojangMappings);
|
||||||
|
files = dep.resolve();
|
||||||
} else {
|
} else {
|
||||||
Dependency dependency = project.getDependencies().create(mappings);
|
Dependency dependency = project.getDependencies().create(mappings);
|
||||||
files = project.getConfigurations().detachedConfiguration(dependency).resolve();
|
files = project.getConfigurations().detachedConfiguration(dependency).resolve();
|
||||||
|
|
|
@ -58,7 +58,7 @@ import net.fabricmc.loom.build.nesting.MergedNestedJarProvider;
|
||||||
import net.fabricmc.loom.build.nesting.NestedDependencyProvider;
|
import net.fabricmc.loom.build.nesting.NestedDependencyProvider;
|
||||||
import net.fabricmc.loom.build.nesting.NestedJarProvider;
|
import net.fabricmc.loom.build.nesting.NestedJarProvider;
|
||||||
import net.fabricmc.loom.configuration.accesswidener.AccessWidenerJarProcessor;
|
import net.fabricmc.loom.configuration.accesswidener.AccessWidenerJarProcessor;
|
||||||
import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider;
|
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
|
||||||
import net.fabricmc.loom.util.Constants;
|
import net.fabricmc.loom.util.Constants;
|
||||||
import net.fabricmc.loom.util.TinyRemapperMappingsHelper;
|
import net.fabricmc.loom.util.TinyRemapperMappingsHelper;
|
||||||
import net.fabricmc.loom.util.ZipReprocessorUtil;
|
import net.fabricmc.loom.util.ZipReprocessorUtil;
|
||||||
|
@ -113,7 +113,7 @@ public class RemapJarTask extends Jar {
|
||||||
throw new FileNotFoundException(input.toString());
|
throw new FileNotFoundException(input.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
MappingsProvider mappingsProvider = extension.getMappingsProvider();
|
MappingsProviderImpl mappingsProvider = extension.getMappingsProvider();
|
||||||
|
|
||||||
String fromM = "named";
|
String fromM = "named";
|
||||||
String toM = "intermediary";
|
String toM = "intermediary";
|
||||||
|
|
|
@ -44,7 +44,7 @@ import org.zeroturnaround.zip.ZipUtil;
|
||||||
import net.fabricmc.loom.LoomGradleExtension;
|
import net.fabricmc.loom.LoomGradleExtension;
|
||||||
import net.fabricmc.loom.configuration.RemappedConfigurationEntry;
|
import net.fabricmc.loom.configuration.RemappedConfigurationEntry;
|
||||||
import net.fabricmc.loom.configuration.providers.LaunchProvider;
|
import net.fabricmc.loom.configuration.providers.LaunchProvider;
|
||||||
import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider;
|
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
|
||||||
import net.fabricmc.loom.util.gradle.ProgressLogger;
|
import net.fabricmc.loom.util.gradle.ProgressLogger;
|
||||||
import net.fabricmc.lorenztiny.TinyMappingsReader;
|
import net.fabricmc.lorenztiny.TinyMappingsReader;
|
||||||
import net.fabricmc.mapping.tree.TinyTree;
|
import net.fabricmc.mapping.tree.TinyTree;
|
||||||
|
@ -163,7 +163,7 @@ public class SourceRemapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
||||||
MappingsProvider mappingsProvider = extension.getMappingsProvider();
|
MappingsProviderImpl mappingsProvider = extension.getMappingsProvider();
|
||||||
|
|
||||||
MappingSet mappings = extension.getOrCreateSrcMappingCache(toNamed ? 1 : 0, () -> {
|
MappingSet mappings = extension.getOrCreateSrcMappingCache(toNamed ? 1 : 0, () -> {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.test.integration
|
||||||
|
|
||||||
|
import net.fabricmc.loom.test.util.ProjectTestTrait
|
||||||
|
import spock.lang.Specification
|
||||||
|
import spock.lang.Unroll
|
||||||
|
|
||||||
|
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
|
||||||
|
|
||||||
|
class ParchmentTest extends Specification implements ProjectTestTrait {
|
||||||
|
@Override
|
||||||
|
String name() {
|
||||||
|
"parchment"
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unroll
|
||||||
|
def "parchment #gradle"() {
|
||||||
|
when:
|
||||||
|
def result = create("build", gradle)
|
||||||
|
|
||||||
|
then:
|
||||||
|
result.task(":build").outcome == SUCCESS
|
||||||
|
|
||||||
|
where:
|
||||||
|
gradle | _
|
||||||
|
DEFAULT_GRADLE | _
|
||||||
|
PRE_RELEASE_GRADLE | _
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.test.unit.layeredmappings
|
||||||
|
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec
|
||||||
|
|
||||||
|
class IntermediaryMappingLayerTest extends LayeredMappingsSpecification {
|
||||||
|
def "Read intermediary mappings" () {
|
||||||
|
setup:
|
||||||
|
mockMappingsProvider.intermediaryTinyFile() >> extractFileFromZip(downloadFile(INTERMEDIARY_1_17_URL, "intermediary.jar"), "mappings/mappings.tiny")
|
||||||
|
when:
|
||||||
|
def mappings = getSingleMapping(new IntermediaryMappingsSpec())
|
||||||
|
def tiny = getTiny(mappings)
|
||||||
|
then:
|
||||||
|
mappings.srcNamespace == "official"
|
||||||
|
mappings.dstNamespaces == ["intermediary", "named"]
|
||||||
|
mappings.classes.size() == 6107
|
||||||
|
mappings.getClass("abc").getDstName(0) == "net/minecraft/class_3191"
|
||||||
|
mappings.getClass("abc").getDstName(1) == "net/minecraft/class_3191"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.test.unit.layeredmappings
|
||||||
|
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpec
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpecBuilder
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsSpec
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.parchment.ParchmentMappingsSpec
|
||||||
|
import org.gradle.api.Action
|
||||||
|
import org.gradle.util.ConfigureUtil
|
||||||
|
import spock.lang.Specification
|
||||||
|
|
||||||
|
class LayeredMappingSpecBuilderTest extends Specification {
|
||||||
|
def "simple mojmap" () {
|
||||||
|
when:
|
||||||
|
def spec = layered() {
|
||||||
|
officalMojangMappings()
|
||||||
|
}
|
||||||
|
def layers = spec.layers()
|
||||||
|
then:
|
||||||
|
spec.version == "layered+hash.961"
|
||||||
|
layers.size() == 2
|
||||||
|
layers[0].class == IntermediaryMappingsSpec
|
||||||
|
layers[1].class == MojangMappingsSpec
|
||||||
|
}
|
||||||
|
|
||||||
|
def "simple mojmap with parchment" () {
|
||||||
|
when:
|
||||||
|
def spec = layered() {
|
||||||
|
officalMojangMappings()
|
||||||
|
parchment("I like cake")
|
||||||
|
}
|
||||||
|
def layers = spec.layers()
|
||||||
|
def parchment = layers[2] as ParchmentMappingsSpec
|
||||||
|
then:
|
||||||
|
spec.version == "layered+hash.863714404"
|
||||||
|
layers.size() == 3
|
||||||
|
layers[0].class == IntermediaryMappingsSpec
|
||||||
|
layers[1].class == MojangMappingsSpec
|
||||||
|
layers[2].class == ParchmentMappingsSpec
|
||||||
|
parchment.mavenNotation() == "I like cake"
|
||||||
|
parchment.removePrefix() == true
|
||||||
|
}
|
||||||
|
|
||||||
|
def "simple mojmap with parchment keep prefix" () {
|
||||||
|
when:
|
||||||
|
def spec = layered() {
|
||||||
|
officalMojangMappings()
|
||||||
|
parchment("I like cake") {
|
||||||
|
it.removePrefix = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
def layers = spec.layers()
|
||||||
|
def parchment = layers[2] as ParchmentMappingsSpec
|
||||||
|
then:
|
||||||
|
spec.version == "layered+hash.863714410"
|
||||||
|
layers.size() == 3
|
||||||
|
layers[0].class == IntermediaryMappingsSpec
|
||||||
|
layers[1].class == MojangMappingsSpec
|
||||||
|
layers[2].class == ParchmentMappingsSpec
|
||||||
|
parchment.mavenNotation() == "I like cake"
|
||||||
|
parchment.removePrefix() == false
|
||||||
|
}
|
||||||
|
|
||||||
|
def "simple mojmap with parchment keep prefix alternate hash" () {
|
||||||
|
when:
|
||||||
|
def spec = layered() {
|
||||||
|
officalMojangMappings()
|
||||||
|
parchment("I really like cake") {
|
||||||
|
it.removePrefix = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
def layers = spec.layers()
|
||||||
|
def parchment = layers[2] as ParchmentMappingsSpec
|
||||||
|
then:
|
||||||
|
spec.version == "layered+hash.1144465487"
|
||||||
|
layers.size() == 3
|
||||||
|
layers[0].class == IntermediaryMappingsSpec
|
||||||
|
layers[1].class == MojangMappingsSpec
|
||||||
|
layers[2].class == ParchmentMappingsSpec
|
||||||
|
parchment.mavenNotation() == "I really like cake"
|
||||||
|
parchment.removePrefix() == false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gradle does this big of magic behind the scenes
|
||||||
|
LayeredMappingSpec layered(@DelegatesTo(LayeredMappingSpecBuilder) Closure cl) {
|
||||||
|
return layeredAction(ConfigureUtil.configureUsing(cl))
|
||||||
|
}
|
||||||
|
|
||||||
|
LayeredMappingSpec layeredAction(Action<LayeredMappingSpecBuilder> action) {
|
||||||
|
LayeredMappingSpecBuilder builder = new LayeredMappingSpecBuilder()
|
||||||
|
action.execute(builder)
|
||||||
|
return builder.build()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.test.unit.layeredmappings
|
||||||
|
|
||||||
|
import groovy.transform.CompileStatic
|
||||||
|
import net.fabricmc.loom.configuration.providers.MinecraftProvider
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpec
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsProcessor
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.MappingContext
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.MappingLayer
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.MappingsProvider
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.MappingsSpec
|
||||||
|
import net.fabricmc.mappingio.format.Tiny2Writer
|
||||||
|
import net.fabricmc.mappingio.tree.MappingTree
|
||||||
|
import net.fabricmc.mappingio.tree.MemoryMappingTree
|
||||||
|
import org.gradle.api.logging.Logger
|
||||||
|
import spock.lang.Specification
|
||||||
|
|
||||||
|
import java.util.zip.ZipFile
|
||||||
|
|
||||||
|
abstract class LayeredMappingsSpecification extends Specification implements LayeredMappingsTestConstants {
|
||||||
|
Logger mockLogger = Mock(Logger)
|
||||||
|
MappingsProvider mockMappingsProvider = Mock(MappingsProvider)
|
||||||
|
MinecraftProvider mockMinecraftProvider = Mock(MinecraftProvider)
|
||||||
|
|
||||||
|
MappingContext mappingContext = new TestMappingContext()
|
||||||
|
|
||||||
|
File tempDir = File.createTempDir()
|
||||||
|
|
||||||
|
Map<String, File> mavenFiles = [:]
|
||||||
|
|
||||||
|
def withMavenFile(String mavenNotation, File file) {
|
||||||
|
mavenFiles.put(mavenNotation, file)
|
||||||
|
}
|
||||||
|
|
||||||
|
File downloadFile(String url, String name) {
|
||||||
|
File dst = new File(tempDir, name)
|
||||||
|
dst.parentFile.mkdirs()
|
||||||
|
dst << new URL(url).newInputStream()
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
File extractFileFromZip(File zipFile, String name) {
|
||||||
|
File dst = new File(tempDir, name)
|
||||||
|
dst.parentFile.mkdirs()
|
||||||
|
|
||||||
|
new ZipFile(zipFile).withCloseable {
|
||||||
|
dst << it.getInputStream(it.getEntry(name))
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryMappingTree getSingleMapping(MappingsSpec<? extends MappingLayer> spec) {
|
||||||
|
MemoryMappingTree mappingTree = new MemoryMappingTree()
|
||||||
|
spec.createLayer(mappingContext).visit(mappingTree)
|
||||||
|
return mappingTree
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryMappingTree getLayeredMappings(MappingsSpec<? extends MappingLayer>... specs) {
|
||||||
|
LayeredMappingSpec spec = new LayeredMappingSpec(specs.toList())
|
||||||
|
LayeredMappingsProcessor processor = new LayeredMappingsProcessor(spec)
|
||||||
|
return processor.getMappings(mappingContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
String getTiny(MemoryMappingTree mappingTree) {
|
||||||
|
def sw = new StringWriter()
|
||||||
|
mappingTree.accept(new Tiny2Writer(sw, false))
|
||||||
|
return sw.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
@CompileStatic
|
||||||
|
class TestMappingContext implements MappingContext {
|
||||||
|
@Override
|
||||||
|
File mavenFile(String mavenNotation) {
|
||||||
|
assert mavenFiles.containsKey(mavenNotation)
|
||||||
|
return mavenFiles.get(mavenNotation)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
MappingsProvider mappingsProvider() {
|
||||||
|
return mockMappingsProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
MinecraftProvider minecraftProvider() {
|
||||||
|
return mockMinecraftProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
File workingDirectory(String name) {
|
||||||
|
return new File(tempDir, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Logger getLogger() {
|
||||||
|
return mockLogger
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.test.unit.layeredmappings
|
||||||
|
|
||||||
|
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta
|
||||||
|
|
||||||
|
interface LayeredMappingsTestConstants {
|
||||||
|
public static final String INTERMEDIARY_1_17_URL = "https://maven.fabricmc.net/net/fabricmc/intermediary/1.17/intermediary-1.17-v2.jar"
|
||||||
|
public static final String INTERMEDIARY_1_16_5_URL = "https://maven.fabricmc.net/net/fabricmc/intermediary/1.16.5/intermediary-1.16.5-v2.jar"
|
||||||
|
|
||||||
|
public static final Map<String, MinecraftVersionMeta.Download> DOWNLOADS_1_17 = [
|
||||||
|
client_mappings:new MinecraftVersionMeta.Download(null, "227d16f520848747a59bef6f490ae19dc290a804", 6431705, "https://launcher.mojang.com/v1/objects/227d16f520848747a59bef6f490ae19dc290a804/client.txt"),
|
||||||
|
server_mappings:new MinecraftVersionMeta.Download(null, "84d80036e14bc5c7894a4fad9dd9f367d3000334", 4948536, "https://launcher.mojang.com/v1/objects/84d80036e14bc5c7894a4fad9dd9f367d3000334/server.txt")
|
||||||
|
]
|
||||||
|
public static final MinecraftVersionMeta VERSION_META_1_17 = new MinecraftVersionMeta(null, null, null, 0, DOWNLOADS_1_17, null, null, null, null, 0, null, null, null)
|
||||||
|
|
||||||
|
public static final Map<String, MinecraftVersionMeta.Download> DOWNLOADS_1_16_5 = [
|
||||||
|
client_mappings:new MinecraftVersionMeta.Download(null, "e3dfb0001e1079a1af72ee21517330edf52e6192", 5746047, "https://launcher.mojang.com/v1/objects/e3dfb0001e1079a1af72ee21517330edf52e6192/client.txt"),
|
||||||
|
server_mappings:new MinecraftVersionMeta.Download(null, "81d5c793695d8cde63afddb40dde88e3a88132ac", 4400926, "https://launcher.mojang.com/v1/objects/81d5c793695d8cde63afddb40dde88e3a88132ac/server.txt")
|
||||||
|
]
|
||||||
|
public static final MinecraftVersionMeta VERSION_META_1_16_5 = new MinecraftVersionMeta(null, null, null, 0, DOWNLOADS_1_16_5, null, null, null, null, 0, null, null, null)
|
||||||
|
|
||||||
|
public static final String PARCHMENT_NOTATION = "org.parchmentmc.data:parchment-1.16.5:20210608-SNAPSHOT@zip"
|
||||||
|
public static final String PARCHMENT_URL = "https://ldtteam.jfrog.io/artifactory/parchmentmc-snapshots/org/parchmentmc/data/parchment-1.16.5/20210608-SNAPSHOT/parchment-1.16.5-20210608-SNAPSHOT.zip"
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.test.unit.layeredmappings
|
||||||
|
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsSpec
|
||||||
|
|
||||||
|
class MojangMappingLayerTest extends LayeredMappingsSpecification {
|
||||||
|
def "Read mojang mappings" () {
|
||||||
|
setup:
|
||||||
|
mockMappingsProvider.intermediaryTinyFile() >> extractFileFromZip(downloadFile(INTERMEDIARY_1_17_URL, "intermediary.jar"), "mappings/mappings.tiny")
|
||||||
|
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_17
|
||||||
|
when:
|
||||||
|
def mappings = getLayeredMappings(
|
||||||
|
new IntermediaryMappingsSpec(),
|
||||||
|
new MojangMappingsSpec()
|
||||||
|
)
|
||||||
|
def tiny = getTiny(mappings)
|
||||||
|
then:
|
||||||
|
mappings.srcNamespace == "named"
|
||||||
|
mappings.dstNamespaces == ["intermediary", "official"]
|
||||||
|
mappings.classes.size() == 6113
|
||||||
|
mappings.classes[0].srcName.hashCode() == 1869546970 // MojMap name, just check the hash
|
||||||
|
mappings.classes[0].getDstName(0) == "net/minecraft/class_2354"
|
||||||
|
mappings.classes[0].methods[0].args.size() == 0 // No Args
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.loom.test.unit.layeredmappings
|
||||||
|
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsSpec
|
||||||
|
import net.fabricmc.loom.configuration.providers.mappings.parchment.ParchmentMappingsSpec
|
||||||
|
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta
|
||||||
|
|
||||||
|
class ParchmentMappingLayerTest extends LayeredMappingsSpecification {
|
||||||
|
def "Read parchment mappings" () {
|
||||||
|
setup:
|
||||||
|
mockMappingsProvider.intermediaryTinyFile() >> extractFileFromZip(downloadFile(INTERMEDIARY_1_16_5_URL, "intermediary.jar"), "mappings/mappings.tiny")
|
||||||
|
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_16_5
|
||||||
|
when:
|
||||||
|
withMavenFile(PARCHMENT_NOTATION, downloadFile(PARCHMENT_URL, "parchment.zip"))
|
||||||
|
def mappings = getLayeredMappings(
|
||||||
|
new IntermediaryMappingsSpec(),
|
||||||
|
new MojangMappingsSpec(),
|
||||||
|
new ParchmentMappingsSpec(PARCHMENT_NOTATION, false)
|
||||||
|
)
|
||||||
|
def tiny = getTiny(mappings)
|
||||||
|
then:
|
||||||
|
mappings.srcNamespace == "named"
|
||||||
|
mappings.dstNamespaces == ["intermediary", "official"]
|
||||||
|
mappings.classes.size() == 5747
|
||||||
|
mappings.classes[0].srcName.hashCode() == -1112444138 // MojMap name, just check the hash
|
||||||
|
mappings.classes[0].getDstName(0) == "net/minecraft/class_2573"
|
||||||
|
mappings.classes[0].methods[0].args[0].srcName == "pStack"
|
||||||
|
}
|
||||||
|
|
||||||
|
def "Read parchment mappings remove prefix" () {
|
||||||
|
setup:
|
||||||
|
mockMappingsProvider.intermediaryTinyFile() >> extractFileFromZip(downloadFile(INTERMEDIARY_1_16_5_URL, "intermediary.jar"), "mappings/mappings.tiny")
|
||||||
|
mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_16_5
|
||||||
|
when:
|
||||||
|
withMavenFile(PARCHMENT_NOTATION, downloadFile(PARCHMENT_URL, "parchment.zip"))
|
||||||
|
def mappings = getLayeredMappings(
|
||||||
|
new IntermediaryMappingsSpec(),
|
||||||
|
new MojangMappingsSpec(),
|
||||||
|
new ParchmentMappingsSpec(PARCHMENT_NOTATION, true)
|
||||||
|
)
|
||||||
|
def tiny = getTiny(mappings)
|
||||||
|
then:
|
||||||
|
mappings.srcNamespace == "named"
|
||||||
|
mappings.dstNamespaces == ["intermediary", "official"]
|
||||||
|
mappings.classes.size() == 5747
|
||||||
|
mappings.classes[0].srcName.hashCode() == -1112444138 // MojMap name, just check the hash
|
||||||
|
mappings.classes[0].getDstName(0) == "net/minecraft/class_2573"
|
||||||
|
mappings.classes[0].methods[0].args[0].srcName == "stack"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
plugins {
|
||||||
|
id 'fabric-loom'
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
name = "ldtteam"
|
||||||
|
url = "https://ldtteam.jfrog.io/artifactory/parchmentmc-snapshots/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
minecraft "com.mojang:minecraft:1.16.5"
|
||||||
|
mappings loom.layered() {
|
||||||
|
officalMojangMappings()
|
||||||
|
parchment("org.parchmentmc.data:parchment-1.16.5:20210608-SNAPSHOT@zip")
|
||||||
|
}
|
||||||
|
|
||||||
|
modImplementation "net.fabricmc:fabric-loader:0.11.3"
|
||||||
|
}
|
Loading…
Reference in New Issue