Support using TinyV2 mappings (#132)
parent
baf976d3f3
commit
8e916f8fb0
13
build.gradle
13
build.gradle
|
@ -39,15 +39,17 @@ dependencies {
|
||||||
implementation ('com.google.guava:guava:28.0-jre')
|
implementation ('com.google.guava:guava:28.0-jre')
|
||||||
|
|
||||||
// game handling utils
|
// game handling utils
|
||||||
implementation ('net.fabricmc:stitch:0.2.1.60') {
|
implementation ('net.fabricmc:stitch:0.3.0.66') {
|
||||||
exclude module: 'enigma'
|
exclude module: 'enigma'
|
||||||
}
|
}
|
||||||
|
|
||||||
// tinyfile management
|
// tinyfile management
|
||||||
implementation ('net.fabricmc:tiny-remapper:0.1.0.38') {
|
implementation ('net.fabricmc:tiny-remapper:0.2.0.52') {
|
||||||
transitive = false
|
transitive = false
|
||||||
}
|
}
|
||||||
implementation ('net.fabricmc:fabric-mixin-compile-extensions:0.1.0.+')
|
implementation ('net.fabricmc:fabric-mixin-compile-extensions:0.2.0.3'){
|
||||||
|
exclude group :"net.fabricmc"
|
||||||
|
}
|
||||||
|
|
||||||
// decompilers
|
// decompilers
|
||||||
implementation ('net.fabricmc:procyon-fabric-compilertools:0.5.35.+')
|
implementation ('net.fabricmc:procyon-fabric-compilertools:0.5.35.+')
|
||||||
|
@ -132,3 +134,8 @@ publishing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
configurations.all {
|
||||||
|
resolutionStrategy {
|
||||||
|
force 'org.codehaus.groovy:groovy-all:2.4.12'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -114,6 +114,7 @@ public class AbstractPlugin implements Plugin<Project> {
|
||||||
includeConfig.setTransitive(false); // Dont get transitive deps
|
includeConfig.setTransitive(false); // Dont get transitive deps
|
||||||
|
|
||||||
project.getConfigurations().maybeCreate(Constants.MAPPINGS);
|
project.getConfigurations().maybeCreate(Constants.MAPPINGS);
|
||||||
|
project.getConfigurations().maybeCreate(Constants.MAPPINGS_FINAL);
|
||||||
|
|
||||||
for (RemappedConfigurationEntry entry : Constants.MOD_COMPILE_ENTRIES) {
|
for (RemappedConfigurationEntry entry : Constants.MOD_COMPILE_ENTRIES) {
|
||||||
Configuration compileModsConfig = project.getConfigurations().maybeCreate(entry.getSourceConfiguration());
|
Configuration compileModsConfig = project.getConfigurations().maybeCreate(entry.getSourceConfiguration());
|
||||||
|
@ -136,8 +137,8 @@ public class AbstractPlugin implements Plugin<Project> {
|
||||||
extendsFrom(Constants.MINECRAFT_NAMED, Constants.MINECRAFT_DEPENDENCIES);
|
extendsFrom(Constants.MINECRAFT_NAMED, Constants.MINECRAFT_DEPENDENCIES);
|
||||||
extendsFrom(Constants.MINECRAFT_INTERMEDIARY, Constants.MINECRAFT_DEPENDENCIES);
|
extendsFrom(Constants.MINECRAFT_INTERMEDIARY, Constants.MINECRAFT_DEPENDENCIES);
|
||||||
|
|
||||||
extendsFrom("compile", Constants.MAPPINGS);
|
extendsFrom("compile", Constants.MAPPINGS_FINAL);
|
||||||
extendsFrom("annotationProcessor", Constants.MAPPINGS);
|
extendsFrom("annotationProcessor", Constants.MAPPINGS_FINAL);
|
||||||
|
|
||||||
configureIDEs();
|
configureIDEs();
|
||||||
configureCompile();
|
configureCompile();
|
||||||
|
@ -156,8 +157,8 @@ public class AbstractPlugin implements Plugin<Project> {
|
||||||
project.getLogger().lifecycle(":setting java compiler args");
|
project.getLogger().lifecycle(":setting java compiler args");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
javaCompileTask.getOptions().getCompilerArgs().add("-AinMapFileNamedIntermediary=" + extension.getMappingsProvider().MAPPINGS_TINY.getCanonicalPath());
|
javaCompileTask.getOptions().getCompilerArgs().add("-AinMapFileNamedIntermediary=" + extension.getMappingsProvider().tinyMappings.getCanonicalPath());
|
||||||
javaCompileTask.getOptions().getCompilerArgs().add("-AoutMapFileNamedIntermediary=" + extension.getMappingsProvider().MAPPINGS_MIXIN_EXPORT.getCanonicalPath());
|
javaCompileTask.getOptions().getCompilerArgs().add("-AoutMapFileNamedIntermediary=" + extension.getMappingsProvider().mappingsMixinExport.getCanonicalPath());
|
||||||
javaCompileTask.getOptions().getCompilerArgs().add("-AoutRefMapFile=" + new File(javaCompileTask.getDestinationDir(), extension.getRefmapName()).getCanonicalPath());
|
javaCompileTask.getOptions().getCompilerArgs().add("-AoutRefMapFile=" + new File(javaCompileTask.getDestinationDir(), extension.getRefmapName()).getCanonicalPath());
|
||||||
javaCompileTask.getOptions().getCompilerArgs().add("-AdefaultObfuscationEnv=named:intermediary");
|
javaCompileTask.getOptions().getCompilerArgs().add("-AdefaultObfuscationEnv=named:intermediary");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -183,8 +184,8 @@ public class AbstractPlugin implements Plugin<Project> {
|
||||||
project.getLogger().warn(":configuring scala compilation processing");
|
project.getLogger().warn(":configuring scala compilation processing");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
task.getOptions().getCompilerArgs().add("-AinMapFileNamedIntermediary=" + extension.getMappingsProvider().MAPPINGS_TINY.getCanonicalPath());
|
task.getOptions().getCompilerArgs().add("-AinMapFileNamedIntermediary=" + extension.getMappingsProvider().tinyMappings.getCanonicalPath());
|
||||||
task.getOptions().getCompilerArgs().add("-AoutMapFileNamedIntermediary=" + extension.getMappingsProvider().MAPPINGS_MIXIN_EXPORT.getCanonicalPath());
|
task.getOptions().getCompilerArgs().add("-AoutMapFileNamedIntermediary=" + extension.getMappingsProvider().mappingsMixinExport.getCanonicalPath());
|
||||||
task.getOptions().getCompilerArgs().add("-AoutRefMapFile=" + new File(task.getDestinationDir(), extension.getRefmapName()).getCanonicalPath());
|
task.getOptions().getCompilerArgs().add("-AoutRefMapFile=" + new File(task.getDestinationDir(), extension.getRefmapName()).getCanonicalPath());
|
||||||
task.getOptions().getCompilerArgs().add("-AdefaultObfuscationEnv=named:intermediary");
|
task.getOptions().getCompilerArgs().add("-AdefaultObfuscationEnv=named:intermediary");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
|
|
||||||
package net.fabricmc.loom.providers;
|
package net.fabricmc.loom.providers;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.lang.ref.SoftReference;
|
import java.lang.ref.SoftReference;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
@ -33,32 +33,32 @@ import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import net.fabricmc.loom.util.StaticPathWatcher;
|
import net.fabricmc.loom.util.StaticPathWatcher;
|
||||||
import net.fabricmc.mappings.Mappings;
|
import net.fabricmc.mapping.tree.TinyMappingFactory;
|
||||||
|
import net.fabricmc.mapping.tree.TinyTree;
|
||||||
|
|
||||||
public final class MappingsCache {
|
public final class MappingsCache {
|
||||||
public static final MappingsCache INSTANCE = new MappingsCache();
|
public static final MappingsCache INSTANCE = new MappingsCache();
|
||||||
|
|
||||||
private final Map<Path, SoftReference<Mappings>> mappingsCache = new HashMap<>();
|
private final Map<Path, SoftReference<TinyTree>> mappingsCache = new HashMap<>();
|
||||||
|
|
||||||
public Mappings get(Path mappingsPath) {
|
//TODO: loom doesn't actually use new mappings when the mappings change until the gradle daemons are stopped
|
||||||
|
public TinyTree get(Path mappingsPath) throws IOException {
|
||||||
mappingsPath = mappingsPath.toAbsolutePath();
|
mappingsPath = mappingsPath.toAbsolutePath();
|
||||||
|
|
||||||
if (StaticPathWatcher.INSTANCE.hasFileChanged(mappingsPath)) {
|
if (StaticPathWatcher.INSTANCE.hasFileChanged(mappingsPath)) {
|
||||||
mappingsCache.remove(mappingsPath);
|
mappingsCache.remove(mappingsPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
SoftReference<Mappings> ref = mappingsCache.get(mappingsPath);
|
SoftReference<TinyTree> ref = mappingsCache.get(mappingsPath);
|
||||||
|
|
||||||
if (ref != null && ref.get() != null) {
|
if (ref != null && ref.get() != null) {
|
||||||
return ref.get();
|
return ref.get();
|
||||||
} else {
|
} else {
|
||||||
try (InputStream stream = Files.newInputStream(mappingsPath)) {
|
try (BufferedReader reader = Files.newBufferedReader(mappingsPath)) {
|
||||||
Mappings mappings = net.fabricmc.mappings.MappingsProvider.readTinyMappings(stream, false);
|
TinyTree mappings = TinyMappingFactory.loadWithDetection(reader);
|
||||||
ref = new SoftReference<>(mappings);
|
ref = new SoftReference<>(mappings);
|
||||||
mappingsCache.put(mappingsPath, ref);
|
mappingsCache.put(mappingsPath, ref);
|
||||||
return mappings;
|
return mappings;
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,25 +24,38 @@
|
||||||
|
|
||||||
package net.fabricmc.loom.providers;
|
package net.fabricmc.loom.providers;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
import java.nio.file.FileSystem;
|
import java.nio.file.FileSystem;
|
||||||
import java.nio.file.FileSystems;
|
import java.nio.file.FileSystems;
|
||||||
import java.nio.file.Files;
|
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 java.util.function.Consumer;
|
||||||
|
|
||||||
|
import com.google.common.net.UrlEscapers;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.apache.tools.ant.util.StringUtils;
|
||||||
import org.gradle.api.Project;
|
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.LoomGradleExtension;
|
||||||
import net.fabricmc.loom.util.Constants;
|
import net.fabricmc.loom.util.Constants;
|
||||||
import net.fabricmc.loom.util.DependencyProvider;
|
import net.fabricmc.loom.util.DependencyProvider;
|
||||||
|
import net.fabricmc.loom.util.DownloadUtil;
|
||||||
import net.fabricmc.loom.util.Version;
|
import net.fabricmc.loom.util.Version;
|
||||||
import net.fabricmc.mappings.Mappings;
|
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.CommandProposeFieldNames;
|
||||||
|
import net.fabricmc.stitch.commands.tinyv2.CommandMergeTinyV2;
|
||||||
|
import net.fabricmc.stitch.commands.tinyv2.CommandReorderTinyV2;
|
||||||
|
|
||||||
//TODO fix local mappings
|
|
||||||
//TODO possibly use maven for mappings, can fix above at the same time
|
|
||||||
public class MappingsProvider extends DependencyProvider {
|
public class MappingsProvider extends DependencyProvider {
|
||||||
public MinecraftMappedProvider mappedProvider;
|
public MinecraftMappedProvider mappedProvider;
|
||||||
|
|
||||||
|
@ -50,13 +63,21 @@ public class MappingsProvider extends DependencyProvider {
|
||||||
public String minecraftVersion;
|
public String minecraftVersion;
|
||||||
public String mappingsVersion;
|
public String mappingsVersion;
|
||||||
|
|
||||||
public File MAPPINGS_DIR;
|
private Path mappingsDir;
|
||||||
public File MAPPINGS_TINY_BASE;
|
private Path mappingsStepsDir;
|
||||||
public File MAPPINGS_TINY;
|
// The mappings that gradle gives us
|
||||||
public File MAPPINGS_MIXIN_EXPORT;
|
private Path baseTinyMappings;
|
||||||
|
// The mappings we use in practice
|
||||||
|
public File tinyMappings;
|
||||||
|
public File tinyMappingsJar;
|
||||||
|
public File mappingsMixinExport;
|
||||||
|
|
||||||
public Mappings getMappings() throws IOException {
|
public void clean() throws IOException {
|
||||||
return MappingsCache.INSTANCE.get(MAPPINGS_TINY.toPath());
|
FileUtils.deleteDirectory(mappingsDir.toFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
public TinyTree getMappings() throws IOException {
|
||||||
|
return MappingsCache.INSTANCE.get(tinyMappings.toPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -66,50 +87,166 @@ public class MappingsProvider extends DependencyProvider {
|
||||||
project.getLogger().lifecycle(":setting up mappings (" + dependency.getDependency().getName() + " " + dependency.getResolvedVersion() + ")");
|
project.getLogger().lifecycle(":setting up mappings (" + dependency.getDependency().getName() + " " + dependency.getResolvedVersion() + ")");
|
||||||
|
|
||||||
String version = dependency.getResolvedVersion();
|
String version = dependency.getResolvedVersion();
|
||||||
File mappingsJar = dependency.resolveFile().orElseThrow(() -> new RuntimeException("Could not find dependency " + dependency));
|
File mappingsJar = dependency.resolveFile().orElseThrow(() -> new RuntimeException("Could not find yarn mappings: " + dependency));
|
||||||
|
|
||||||
this.mappingsName = dependency.getDependency().getGroup() + "." + dependency.getDependency().getName();
|
this.mappingsName = StringUtils.removeSuffix(dependency.getDependency().getGroup() + "." + dependency.getDependency().getName(), "-unmerged");
|
||||||
|
|
||||||
|
boolean isV2 = doesJarContainV2Mappings(mappingsJar.toPath());
|
||||||
|
|
||||||
Version mappingsVersion = new Version(version);
|
Version mappingsVersion = new Version(version);
|
||||||
this.minecraftVersion = mappingsVersion.getMinecraftVersion();
|
this.minecraftVersion = mappingsVersion.getMinecraftVersion();
|
||||||
this.mappingsVersion = mappingsVersion.getMappingsVersion();
|
this.mappingsVersion = mappingsVersion.getMappingsVersion() + (isV2 ? "-v2" : "");
|
||||||
|
|
||||||
initFiles(project);
|
initFiles(project);
|
||||||
|
|
||||||
if (!MAPPINGS_DIR.exists()) {
|
Files.createDirectories(mappingsDir);
|
||||||
MAPPINGS_DIR.mkdir();
|
Files.createDirectories(mappingsStepsDir);
|
||||||
|
|
||||||
|
String[] depStringSplit = dependency.getDepString().split(":");
|
||||||
|
String jarClassifier = "final";
|
||||||
|
|
||||||
|
if (depStringSplit.length >= 4) {
|
||||||
|
jarClassifier = jarClassifier + depStringSplit[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MAPPINGS_TINY_BASE.exists() || !MAPPINGS_TINY.exists()) {
|
tinyMappings = mappingsDir.resolve(StringUtils.removeSuffix(mappingsJar.getName(), ".jar") + ".tiny").toFile();
|
||||||
if (!MAPPINGS_TINY_BASE.exists()) {
|
tinyMappingsJar = new File(extension.getUserCache(), mappingsJar.getName().replace(".jar", "-" + jarClassifier + ".jar"));
|
||||||
project.getLogger().lifecycle(":extracting " + mappingsJar.getName());
|
|
||||||
|
|
||||||
try (FileSystem fileSystem = FileSystems.newFileSystem(mappingsJar.toPath(), null)) {
|
if (!tinyMappings.exists()) {
|
||||||
Path fileToExtract = fileSystem.getPath("mappings/mappings.tiny");
|
storeMappings(project, minecraftProvider, mappingsJar.toPath());
|
||||||
Files.copy(fileToExtract, MAPPINGS_TINY_BASE.toPath());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MAPPINGS_TINY.exists()) {
|
if (!tinyMappingsJar.exists()) {
|
||||||
MAPPINGS_TINY.delete();
|
ZipUtil.pack(new ZipEntrySource[] {new FileSource("mappings/mappings.tiny", tinyMappings)}, tinyMappingsJar);
|
||||||
}
|
}
|
||||||
|
|
||||||
project.getLogger().lifecycle(":populating field names");
|
addDependency(tinyMappingsJar, project, Constants.MAPPINGS_FINAL);
|
||||||
new CommandProposeFieldNames().run(new String[]{minecraftProvider.MINECRAFT_MERGED_JAR.getAbsolutePath(), MAPPINGS_TINY_BASE.getAbsolutePath(), MAPPINGS_TINY.getAbsolutePath()});
|
|
||||||
}
|
|
||||||
|
|
||||||
mappedProvider = new MinecraftMappedProvider();
|
mappedProvider = new MinecraftMappedProvider();
|
||||||
mappedProvider.initFiles(project, minecraftProvider, this);
|
mappedProvider.initFiles(project, minecraftProvider, this);
|
||||||
mappedProvider.provide(dependency, project, extension, postPopulationScheduler);
|
mappedProvider.provide(dependency, project, extension, postPopulationScheduler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initFiles(Project project) {
|
private void storeMappings(Project project, MinecraftProvider minecraftProvider, Path yarnJar) throws IOException {
|
||||||
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
project.getLogger().lifecycle(":extracting " + yarnJar.getFileName());
|
||||||
MAPPINGS_DIR = new File(extension.getUserCache(), "mappings");
|
|
||||||
|
|
||||||
MAPPINGS_TINY_BASE = new File(MAPPINGS_DIR, mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion + "-base");
|
try (FileSystem fileSystem = FileSystems.newFileSystem(yarnJar, null)) {
|
||||||
MAPPINGS_TINY = new File(MAPPINGS_DIR, mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion);
|
extractMappings(fileSystem, baseTinyMappings);
|
||||||
MAPPINGS_MIXIN_EXPORT = new File(extension.getProjectBuildCache(), "mixin-map-" + minecraftVersion + "-" + mappingsVersion + ".tiny");
|
}
|
||||||
|
|
||||||
|
if (baseMappingsAreV2()) {
|
||||||
|
// These are unmerged v2 mappings
|
||||||
|
|
||||||
|
// Download and extract intermediary
|
||||||
|
String encodedMinecraftVersion = UrlEscapers.urlFragmentEscaper().escape(minecraftVersion);
|
||||||
|
String intermediaryArtifactUrl = "https://maven.fabricmc.net/net/fabricmc/intermediary/" + encodedMinecraftVersion + "/intermediary-" + encodedMinecraftVersion + "-v2.jar";
|
||||||
|
Path intermediaryJar = mappingsStepsDir.resolve("v2-intermediary-" + minecraftVersion + ".jar");
|
||||||
|
DownloadUtil.downloadIfChanged(new URL(intermediaryArtifactUrl), intermediaryJar.toFile(), project.getLogger());
|
||||||
|
|
||||||
|
mergeAndSaveMappings(project, intermediaryJar, 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, 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 mergeAndSaveMappings(Project project, Path unmergedIntermediaryJar, Path unmergedYarnJar) throws IOException {
|
||||||
|
Path unmergedIntermediary = Paths.get(mappingsStepsDir.toString(), "unmerged-intermediary.tiny");
|
||||||
|
project.getLogger().info(":extracting " + unmergedIntermediaryJar.getFileName());
|
||||||
|
|
||||||
|
try (FileSystem unmergedIntermediaryFs = FileSystems.newFileSystem(unmergedIntermediaryJar, null)) {
|
||||||
|
extractMappings(unmergedIntermediaryFs, unmergedIntermediary);
|
||||||
|
}
|
||||||
|
|
||||||
|
Path unmergedYarn = Paths.get(mappingsStepsDir.toString(), "unmerged-yarn.tiny");
|
||||||
|
project.getLogger().info(":extracting " + unmergedYarnJar.getFileName());
|
||||||
|
|
||||||
|
try (FileSystem unmergedYarnJarFs = FileSystems.newFileSystem(unmergedYarnJar, null)) {
|
||||||
|
extractMappings(unmergedYarnJarFs, unmergedYarn);
|
||||||
|
}
|
||||||
|
|
||||||
|
Path invertedIntermediary = Paths.get(mappingsStepsDir.toString(), "inverted-intermediary.tiny");
|
||||||
|
reorderMappings(unmergedIntermediary, 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.MINECRAFT_MERGED_JAR.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(Project project) {
|
||||||
|
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
||||||
|
mappingsDir = extension.getUserCache().toPath().resolve("mappings");
|
||||||
|
mappingsStepsDir = mappingsDir.resolve("steps");
|
||||||
|
|
||||||
|
baseTinyMappings = mappingsDir.resolve(mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion + "-base");
|
||||||
|
mappingsMixinExport = new File(extension.getProjectBuildCache(), "mixin-map-" + minecraftVersion + "-" + mappingsVersion + ".tiny");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -39,11 +39,14 @@ public class MinecraftMappedProvider extends DependencyProvider {
|
||||||
public File MINECRAFT_MAPPED_JAR;
|
public File MINECRAFT_MAPPED_JAR;
|
||||||
public File MINECRAFT_INTERMEDIARY_JAR;
|
public File MINECRAFT_INTERMEDIARY_JAR;
|
||||||
|
|
||||||
|
public MinecraftMappedProvider() {
|
||||||
|
}
|
||||||
|
|
||||||
private MinecraftProvider minecraftProvider;
|
private MinecraftProvider minecraftProvider;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void provide(DependencyInfo dependency, Project project, LoomGradleExtension extension, Consumer<Runnable> postPopulationScheduler) throws Exception {
|
public void provide(DependencyInfo dependency, Project project, LoomGradleExtension extension, Consumer<Runnable> postPopulationScheduler) throws Exception {
|
||||||
if (!extension.getMappingsProvider().MAPPINGS_TINY.exists()) {
|
if (!extension.getMappingsProvider().tinyMappings.exists()) {
|
||||||
throw new RuntimeException("mappings file not found");
|
throw new RuntimeException("mappings file not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,17 +70,28 @@ public class MinecraftMappedProvider extends DependencyProvider {
|
||||||
throw new RuntimeException("mapped jar not found");
|
throw new RuntimeException("mapped jar not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
String version = minecraftProvider.minecraftVersion + "-mapped-" + extension.getMappingsProvider().mappingsName + "-" + extension.getMappingsProvider().mappingsVersion;
|
MappingsProvider mappingsProvider = extension.getMappingsProvider();
|
||||||
project.getDependencies().add(Constants.MINECRAFT_NAMED, project.getDependencies().module("net.minecraft:minecraft:" + version));
|
project.getDependencies().add(Constants.MINECRAFT_NAMED,
|
||||||
version = minecraftProvider.minecraftVersion + "-intermediary-" + extension.getMappingsProvider().mappingsName;
|
project.getDependencies().module("net.minecraft:minecraft:" + getNamedJarVersionString(mappingsProvider.mappingsName, mappingsProvider.mappingsVersion)));
|
||||||
project.getDependencies().add(Constants.MINECRAFT_INTERMEDIARY, project.getDependencies().module("net.minecraft:minecraft:" + version));
|
project.getDependencies().add(Constants.MINECRAFT_INTERMEDIARY,
|
||||||
|
project.getDependencies().module("net.minecraft:minecraft:" + getIntermediaryJarVersionString(mappingsProvider.mappingsName, mappingsProvider.mappingsVersion)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initFiles(Project project, MinecraftProvider minecraftProvider, MappingsProvider mappingsProvider) {
|
public void initFiles(Project project, MinecraftProvider minecraftProvider, MappingsProvider mappingsProvider) {
|
||||||
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
||||||
this.minecraftProvider = minecraftProvider;
|
this.minecraftProvider = minecraftProvider;
|
||||||
MINECRAFT_INTERMEDIARY_JAR = new File(extension.getUserCache(), "minecraft-" + minecraftProvider.minecraftVersion + "-intermediary-" + mappingsProvider.mappingsName + ".jar");
|
MINECRAFT_INTERMEDIARY_JAR = new File(extension.getUserCache(),
|
||||||
MINECRAFT_MAPPED_JAR = new File(extension.getUserCache(), "minecraft-" + minecraftProvider.minecraftVersion + "-mapped-" + mappingsProvider.mappingsName + "-" + mappingsProvider.mappingsVersion + ".jar");
|
"minecraft-" + getIntermediaryJarVersionString(mappingsProvider.mappingsName, mappingsProvider.mappingsVersion) + ".jar");
|
||||||
|
MINECRAFT_MAPPED_JAR = new File(extension.getUserCache(),
|
||||||
|
"minecraft-" + getNamedJarVersionString(mappingsProvider.mappingsName, mappingsProvider.mappingsVersion) + ".jar");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getNamedJarVersionString(String mappingsName, String mappingsVersion) {
|
||||||
|
return minecraftProvider.minecraftVersion + "-mapped-" + mappingsName + "-" + mappingsVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getIntermediaryJarVersionString(String mappingsName, String mappingsVersion) {
|
||||||
|
return minecraftProvider.minecraftVersion + "-intermediary-" + mappingsName + "-" + mappingsVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<File> getMapperPaths() {
|
public Collection<File> getMapperPaths() {
|
||||||
|
|
|
@ -36,14 +36,12 @@ import net.fabricmc.loom.util.DeletingFileVisitor;
|
||||||
public class CleanLoomMappings extends AbstractLoomTask {
|
public class CleanLoomMappings extends AbstractLoomTask {
|
||||||
@TaskAction
|
@TaskAction
|
||||||
public void run() {
|
public void run() {
|
||||||
|
try {
|
||||||
Project project = this.getProject();
|
Project project = this.getProject();
|
||||||
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
||||||
extension.getMappingsProvider().MAPPINGS_TINY.delete();
|
extension.getMappingsProvider().clean();
|
||||||
extension.getMappingsProvider().MAPPINGS_TINY_BASE.delete();
|
|
||||||
extension.getMinecraftMappedProvider().getIntermediaryJar().delete();
|
extension.getMinecraftMappedProvider().getIntermediaryJar().delete();
|
||||||
extension.getMinecraftMappedProvider().getMappedJar().delete();
|
extension.getMinecraftMappedProvider().getMappedJar().delete();
|
||||||
|
|
||||||
try {
|
|
||||||
Files.walkFileTree(extension.getRootProjectBuildCache().toPath(), new DeletingFileVisitor());
|
Files.walkFileTree(extension.getRootProjectBuildCache().toPath(), new DeletingFileVisitor());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
|
|
@ -24,27 +24,41 @@
|
||||||
|
|
||||||
package net.fabricmc.loom.task;
|
package net.fabricmc.loom.task;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
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.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
import com.google.common.net.UrlEscapers;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.cadixdev.lorenz.MappingSet;
|
import org.cadixdev.lorenz.MappingSet;
|
||||||
import org.cadixdev.lorenz.io.MappingsReader;
|
import org.cadixdev.lorenz.io.MappingsReader;
|
||||||
|
import org.cadixdev.lorenz.model.ClassMapping;
|
||||||
|
import org.cadixdev.lorenz.model.Mapping;
|
||||||
import org.cadixdev.mercury.Mercury;
|
import org.cadixdev.mercury.Mercury;
|
||||||
import org.cadixdev.mercury.remapper.MercuryRemapper;
|
import org.cadixdev.mercury.remapper.MercuryRemapper;
|
||||||
import org.gradle.api.Project;
|
import org.gradle.api.Project;
|
||||||
import org.gradle.api.tasks.TaskAction;
|
import org.gradle.api.tasks.TaskAction;
|
||||||
|
|
||||||
import net.fabricmc.loom.LoomGradleExtension;
|
import net.fabricmc.loom.LoomGradleExtension;
|
||||||
import net.fabricmc.loom.util.Constants;
|
import net.fabricmc.loom.providers.MappingsProvider;
|
||||||
import net.fabricmc.loom.util.Version;
|
import net.fabricmc.loom.providers.MinecraftMappedProvider;
|
||||||
import net.fabricmc.mappings.ClassEntry;
|
import net.fabricmc.loom.util.SourceRemapper;
|
||||||
import net.fabricmc.mappings.EntryTriple;
|
import net.fabricmc.mapping.tree.ClassDef;
|
||||||
import net.fabricmc.mappings.FieldEntry;
|
import net.fabricmc.mapping.tree.Descriptored;
|
||||||
import net.fabricmc.mappings.Mappings;
|
import net.fabricmc.mapping.tree.FieldDef;
|
||||||
import net.fabricmc.mappings.MethodEntry;
|
import net.fabricmc.mapping.tree.MethodDef;
|
||||||
|
import net.fabricmc.mapping.tree.TinyMappingFactory;
|
||||||
|
import net.fabricmc.mapping.tree.TinyTree;
|
||||||
|
|
||||||
public class MigrateMappingsTask extends AbstractLoomTask {
|
public class MigrateMappingsTask extends AbstractLoomTask {
|
||||||
@TaskAction
|
@TaskAction
|
||||||
|
@ -55,75 +69,95 @@ public class MigrateMappingsTask extends AbstractLoomTask {
|
||||||
|
|
||||||
project.getLogger().lifecycle(":loading mappings");
|
project.getLogger().lifecycle(":loading mappings");
|
||||||
|
|
||||||
File mappingsFile = null;
|
String inputDir = (String) properties.get("inputDir");
|
||||||
|
if (inputDir == null) inputDir = "src/main/java";
|
||||||
|
String outputDir = (String) properties.get("outputDir");
|
||||||
|
if (outputDir == null) outputDir = "remappedSrc";
|
||||||
|
String officialMappingsVersion = (String) properties.get("targetMappings");
|
||||||
|
String localMappingsPath = (String) properties.get("targetLocalMappings");
|
||||||
|
|
||||||
if (properties.containsKey("targetMappingsFile")) {
|
if (officialMappingsVersion != null && localMappingsPath != null) {
|
||||||
mappingsFile = new File((String) properties.get("targetMappingsFile"));
|
throw new IllegalArgumentException("targetMappings and targetLocalMappings are mutually exclusive;"
|
||||||
} else if (properties.containsKey("targetMappingsArtifact")) {
|
+ " you either specify an official yarn mappings version with targetMappings, "
|
||||||
String[] artifactName = ((String) properties.get("targetMappingsArtifact")).split(":");
|
+ "or a local one with targetLocalMappings.");
|
||||||
|
|
||||||
if (artifactName.length != 3) {
|
|
||||||
throw new RuntimeException("Invalid artifact name: " + properties.get("targetMappingsArtifact"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String mappingsName = artifactName[0] + "." + artifactName[1];
|
if (officialMappingsVersion == null && localMappingsPath == null) {
|
||||||
|
throw new IllegalArgumentException("You must specify a new mappings version with -PtargetMappings (or local mappings with -PtargetLocalMappings).");
|
||||||
Version v = new Version(artifactName[2]);
|
|
||||||
String minecraftVersion = v.getMinecraftVersion();
|
|
||||||
String mappingsVersion = v.getMappingsVersion();
|
|
||||||
|
|
||||||
mappingsFile = new File(extension.getMappingsProvider().MAPPINGS_DIR, mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mappingsFile == null || !mappingsFile.exists()) {
|
boolean useLocalMappings = localMappingsPath != null;
|
||||||
throw new RuntimeException("Could not find mappings file: " + (mappingsFile != null ? mappingsFile : "null"));
|
|
||||||
|
if (useLocalMappings && !Files.exists(Paths.get(localMappingsPath))) {
|
||||||
|
throw new IllegalArgumentException("Can't find local mappings in specified location: " + localMappingsPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!properties.containsKey("inputDir") || !properties.containsKey("outputDir")) {
|
String targetMappingsName = useLocalMappings ? localMappingsPath : officialMappingsVersion;
|
||||||
throw new RuntimeException("Must specify input and output dir!");
|
|
||||||
|
Path inputDirPath = Paths.get(System.getProperty("user.dir"), inputDir);
|
||||||
|
Path outputDirPath = Paths.get(System.getProperty("user.dir"), outputDir);
|
||||||
|
|
||||||
|
if (!Files.exists(inputDirPath) || !Files.isDirectory(inputDirPath)) {
|
||||||
|
throw new IllegalArgumentException("Could not find input directory: " + inputDirPath.toAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
File inputDir = new File((String) properties.get("inputDir"));
|
Files.createDirectories(outputDirPath);
|
||||||
File outputDir = new File((String) properties.get("outputDir"));
|
|
||||||
|
|
||||||
if (!inputDir.exists() || !inputDir.isDirectory()) {
|
MappingsProvider mappingsProvider = extension.getMappingsProvider();
|
||||||
throw new RuntimeException("Could not find input directory: " + inputDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!outputDir.exists()) {
|
try {
|
||||||
if (!outputDir.mkdirs()) {
|
TinyTree currentMappings = mappingsProvider.getMappings();
|
||||||
throw new RuntimeException("Could not create output directory:" + outputDir);
|
TinyTree targetMappings = getMappings(project, targetMappingsName, useLocalMappings);
|
||||||
|
migrateMappings(project, extension.getMinecraftMappedProvider(), inputDirPath, outputDirPath, currentMappings, targetMappings, extension);
|
||||||
|
project.getLogger().lifecycle(":remapped project written to " + outputDirPath.toAbsolutePath());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new IllegalArgumentException("Could not find mappings for version " + officialMappingsVersion, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Mappings sourceMappings = extension.getMappingsProvider().getMappings();
|
private TinyTree getMappings(Project project, String mappingsVersionOrPath, boolean useLocalMappings) throws IOException {
|
||||||
Mappings targetMappings;
|
Path migrateMappingsDir = Files.createTempDirectory("migrate");
|
||||||
|
Path localMappingsOfVersion = migrateMappingsDir.resolve(mappingsVersionOrPath + ".tiny");
|
||||||
|
|
||||||
try (FileInputStream stream = new FileInputStream(mappingsFile)) {
|
if (!Files.exists(localMappingsOfVersion)) {
|
||||||
targetMappings = net.fabricmc.mappings.MappingsProvider.readTinyMappings(stream, false);
|
if (useLocalMappings) {
|
||||||
|
Files.copy(Paths.get(mappingsVersionOrPath), localMappingsOfVersion);
|
||||||
|
} else {
|
||||||
|
String versionRelativePath = UrlEscapers.urlFragmentEscaper().escape(mappingsVersionOrPath);
|
||||||
|
String artifactUrl = "https://maven.fabricmc.net/net/fabricmc/yarn/" + versionRelativePath + "/yarn-" + versionRelativePath + ".jar";
|
||||||
|
File mappingsJar = File.createTempFile("migrateMappingsJar", ".jar");
|
||||||
|
project.getLogger().lifecycle(":downloading new mappings from " + artifactUrl);
|
||||||
|
FileUtils.copyURLToFile(new URL(artifactUrl), mappingsJar);
|
||||||
|
|
||||||
|
try (FileSystem jar = FileSystems.newFileSystem(mappingsJar.toPath(), null)) {
|
||||||
|
if (!Files.exists(migrateMappingsDir)) Files.createDirectory(migrateMappingsDir);
|
||||||
|
MappingsProvider.extractMappings(jar, localMappingsOfVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try (BufferedReader reader = Files.newBufferedReader(localMappingsOfVersion)) {
|
||||||
|
return TinyMappingFactory.loadWithDetection(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void migrateMappings(Project project, MinecraftMappedProvider minecraftMappedProvider,
|
||||||
|
Path inputDir, Path outputDir, TinyTree currentMappings, TinyTree targetMappings, LoomGradleExtension extension
|
||||||
|
) throws IOException {
|
||||||
project.getLogger().lifecycle(":joining mappings");
|
project.getLogger().lifecycle(":joining mappings");
|
||||||
MappingSet mappingSet = new MappingsJoiner(sourceMappings, targetMappings, "intermediary", "named").read();
|
MappingSet mappingSet = new MappingsJoiner(currentMappings, targetMappings,
|
||||||
|
"intermediary", "named").read();
|
||||||
|
|
||||||
project.getLogger().lifecycle(":remapping");
|
project.getLogger().lifecycle(":remapping");
|
||||||
Mercury mercury = new Mercury();
|
Mercury mercury = SourceRemapper.createMercuryWithClassPath(project, false);
|
||||||
|
|
||||||
for (File file : project.getConfigurations().getByName(Constants.MINECRAFT_DEPENDENCIES).getFiles()) {
|
mercury.getClassPath().add(minecraftMappedProvider.MINECRAFT_MAPPED_JAR.toPath());
|
||||||
mercury.getClassPath().add(file.toPath());
|
mercury.getClassPath().add(minecraftMappedProvider.MINECRAFT_INTERMEDIARY_JAR.toPath());
|
||||||
}
|
|
||||||
|
|
||||||
for (File file : project.getConfigurations().getByName("compileClasspath").getFiles()) {
|
|
||||||
mercury.getClassPath().add(file.toPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
mercury.getClassPath().add(extension.getMinecraftMappedProvider().MINECRAFT_MAPPED_JAR.toPath());
|
|
||||||
mercury.getClassPath().add(extension.getMinecraftMappedProvider().MINECRAFT_INTERMEDIARY_JAR.toPath());
|
|
||||||
|
|
||||||
mercury.getProcessors().add(MercuryRemapper.create(mappingSet));
|
mercury.getProcessors().add(MercuryRemapper.create(mappingSet));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mercury.rewrite(inputDir.toPath(), outputDir.toPath());
|
mercury.rewrite(inputDir, outputDir);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
project.getLogger().warn("Could not remap fully!", e);
|
project.getLogger().warn("Could not remap fully!", e);
|
||||||
}
|
}
|
||||||
|
@ -133,10 +167,19 @@ public class MigrateMappingsTask extends AbstractLoomTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class MappingsJoiner extends MappingsReader {
|
public static class MappingsJoiner extends MappingsReader {
|
||||||
private final Mappings sourceMappings, targetMappings;
|
private final TinyTree sourceMappings, targetMappings;
|
||||||
private final String fromNamespace, toNamespace;
|
private final String fromNamespace, toNamespace;
|
||||||
|
|
||||||
public MappingsJoiner(Mappings sourceMappings, Mappings targetMappings, String fromNamespace, String toNamespace) {
|
/**
|
||||||
|
* Say A is the source mappings and B is the target mappings.
|
||||||
|
* It does not map from intermediary to named but rather maps from named-A to named-B, by matching intermediary names.
|
||||||
|
* It goes through all of the intermediary names of A, and for every such intermediary name, call it I,
|
||||||
|
* matches the named mapping of I in A, with the named mapping of I in B.
|
||||||
|
* As you might imagine, this requires intermediary mappings to be stable across all versions.
|
||||||
|
* Since we only use intermediary names (and not descriptors) to match, and intermediary names are unique,
|
||||||
|
* this will migrate methods that have had their signature changed too.
|
||||||
|
*/
|
||||||
|
public MappingsJoiner(TinyTree sourceMappings, TinyTree targetMappings, String fromNamespace, String toNamespace) {
|
||||||
this.sourceMappings = sourceMappings;
|
this.sourceMappings = sourceMappings;
|
||||||
this.targetMappings = targetMappings;
|
this.targetMappings = targetMappings;
|
||||||
this.fromNamespace = fromNamespace;
|
this.fromNamespace = fromNamespace;
|
||||||
|
@ -144,40 +187,51 @@ public class MigrateMappingsTask extends AbstractLoomTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MappingSet read(MappingSet mappings) throws IOException {
|
public MappingSet read(MappingSet mappings) {
|
||||||
Map<String, ClassEntry> targetClasses = new HashMap<>();
|
Map<String, ClassDef> targetClasses = new HashMap<>();
|
||||||
Map<EntryTriple, FieldEntry> targetFields = new HashMap<>();
|
Map<String, FieldDef> targetFields = new HashMap<>();
|
||||||
Map<EntryTriple, MethodEntry> targetMethods = new HashMap<>();
|
Map<String, MethodDef> targetMethods = new HashMap<>();
|
||||||
|
|
||||||
targetMappings.getClassEntries().forEach((c) -> targetClasses.put(c.get(fromNamespace), c));
|
for (ClassDef newClass : targetMappings.getClasses()) {
|
||||||
targetMappings.getFieldEntries().forEach((c) -> targetFields.put(c.get(fromNamespace), c));
|
targetClasses.put(newClass.getName(fromNamespace), newClass);
|
||||||
targetMappings.getMethodEntries().forEach((c) -> targetMethods.put(c.get(fromNamespace), c));
|
|
||||||
|
|
||||||
for (ClassEntry entry : sourceMappings.getClassEntries()) {
|
for (FieldDef field : newClass.getFields()) {
|
||||||
String from = entry.get(toNamespace);
|
targetFields.put(field.getName(fromNamespace), field);
|
||||||
String to = targetClasses.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace);
|
|
||||||
|
|
||||||
mappings.getOrCreateClassMapping(from).setDeobfuscatedName(to);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (FieldEntry entry : sourceMappings.getFieldEntries()) {
|
for (MethodDef method : newClass.getMethods()) {
|
||||||
EntryTriple fromEntry = entry.get(toNamespace);
|
targetMethods.put(method.getName(fromNamespace), method);
|
||||||
EntryTriple toEntry = targetFields.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace);
|
}
|
||||||
|
|
||||||
mappings.getOrCreateClassMapping(fromEntry.getOwner()).getOrCreateFieldMapping(fromEntry.getName(), fromEntry.getDesc()).setDeobfuscatedName(toEntry.getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (MethodEntry entry : sourceMappings.getMethodEntries()) {
|
for (ClassDef oldClass : sourceMappings.getClasses()) {
|
||||||
EntryTriple fromEntry = entry.get(toNamespace);
|
String namedMappingOfSourceMapping = oldClass.getName(toNamespace);
|
||||||
EntryTriple toEntry = targetMethods.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace);
|
String namedMappingOfTargetMapping = targetClasses.getOrDefault(oldClass.getName(fromNamespace), oldClass).getName(toNamespace);
|
||||||
|
|
||||||
mappings.getOrCreateClassMapping(fromEntry.getOwner()).getOrCreateMethodMapping(fromEntry.getName(), fromEntry.getDesc()).setDeobfuscatedName(toEntry.getName());
|
ClassMapping classMapping = mappings.getOrCreateClassMapping(namedMappingOfSourceMapping).setDeobfuscatedName(namedMappingOfTargetMapping);
|
||||||
|
|
||||||
|
mapMembers(oldClass.getFields(), targetFields, classMapping::getOrCreateFieldMapping);
|
||||||
|
mapMembers(oldClass.getMethods(), targetMethods, classMapping::getOrCreateMethodMapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mappings;
|
return mappings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private <T extends Descriptored> void mapMembers(Collection<T> oldMembers, Map<String, T> newMembers,
|
||||||
|
BiFunction<String, String, Mapping> mapper) {
|
||||||
|
for (T oldMember : oldMembers) {
|
||||||
|
String oldName = oldMember.getName(toNamespace);
|
||||||
|
String oldDescriptor = oldMember.getDescriptor(toNamespace);
|
||||||
|
// We only use the intermediary name (and not the descriptor) because every method has a unique intermediary name
|
||||||
|
String newName = newMembers.getOrDefault(oldMember.getName(fromNamespace), oldMember).getName(toNamespace);
|
||||||
|
|
||||||
|
mapper.apply(oldName, oldDescriptor).setDeobfuscatedName(newName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException { }
|
public void close() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,12 +80,12 @@ public class RemapJarTask extends Jar {
|
||||||
);
|
);
|
||||||
Path[] classpath = classpathFiles.stream().map(File::toPath).filter((p) -> !input.equals(p) && Files.exists(p)).toArray(Path[]::new);
|
Path[] classpath = classpathFiles.stream().map(File::toPath).filter((p) -> !input.equals(p) && Files.exists(p)).toArray(Path[]::new);
|
||||||
|
|
||||||
File mixinMapFile = mappingsProvider.MAPPINGS_MIXIN_EXPORT;
|
File mixinMapFile = mappingsProvider.mappingsMixinExport;
|
||||||
Path mixinMapPath = mixinMapFile.toPath();
|
Path mixinMapPath = mixinMapFile.toPath();
|
||||||
|
|
||||||
TinyRemapper.Builder remapperBuilder = TinyRemapper.newRemapper();
|
TinyRemapper.Builder remapperBuilder = TinyRemapper.newRemapper();
|
||||||
|
|
||||||
remapperBuilder = remapperBuilder.withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM));
|
remapperBuilder = remapperBuilder.withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM, false));
|
||||||
|
|
||||||
if (mixinMapFile.exists()) {
|
if (mixinMapFile.exists()) {
|
||||||
remapperBuilder = remapperBuilder.withMappings(TinyUtils.createTinyMappingProvider(mixinMapPath, fromM, toM));
|
remapperBuilder = remapperBuilder.withMappings(TinyUtils.createTinyMappingProvider(mixinMapPath, fromM, toM));
|
||||||
|
|
|
@ -50,4 +50,5 @@ public class Constants {
|
||||||
public static final String MINECRAFT_NAMED = "minecraftNamed";
|
public static final String MINECRAFT_NAMED = "minecraftNamed";
|
||||||
public static final String MINECRAFT_LINEMAPPED = "minecraftLinemapped";
|
public static final String MINECRAFT_LINEMAPPED = "minecraftLinemapped";
|
||||||
public static final String MAPPINGS = "mappings";
|
public static final String MAPPINGS = "mappings";
|
||||||
|
public static final String MAPPINGS_FINAL = "mappingsFinal";
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,11 @@ public class MapJarsTiny {
|
||||||
|
|
||||||
project.getLogger().lifecycle(":remapping minecraft (TinyRemapper, " + fromM + " -> " + toM + ")");
|
project.getLogger().lifecycle(":remapping minecraft (TinyRemapper, " + fromM + " -> " + toM + ")");
|
||||||
|
|
||||||
TinyRemapper remapper = TinyRemapper.newRemapper().withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM)).renameInvalidLocals(true).rebuildSourceFilenames(true).build();
|
TinyRemapper remapper = TinyRemapper.newRemapper()
|
||||||
|
.withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM, true))
|
||||||
|
.renameInvalidLocals(true)
|
||||||
|
.rebuildSourceFilenames(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(output).build()) {
|
try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(output).build()) {
|
||||||
outputConsumer.addNonClassFiles(input);
|
outputConsumer.addNonClassFiles(input);
|
||||||
|
@ -64,7 +68,7 @@ public class MapJarsTiny {
|
||||||
remapper.readInputs(input);
|
remapper.readInputs(input);
|
||||||
remapper.apply(outputConsumer);
|
remapper.apply(outputConsumer);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Failed to remap JAR", e);
|
throw new RuntimeException("Failed to remap JAR " + input + " with mappings from " + mappingsProvider.tinyMappings, e);
|
||||||
} finally {
|
} finally {
|
||||||
remapper.finish();
|
remapper.finish();
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,13 +41,12 @@ import com.google.gson.Gson;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.gradle.api.Project;
|
||||||
|
import org.gradle.api.artifacts.Configuration;
|
||||||
import org.zeroturnaround.zip.ZipUtil;
|
import org.zeroturnaround.zip.ZipUtil;
|
||||||
import org.zeroturnaround.zip.commons.FileUtils;
|
import org.zeroturnaround.zip.commons.FileUtils;
|
||||||
import org.zeroturnaround.zip.transform.StringZipEntryTransformer;
|
import org.zeroturnaround.zip.transform.StringZipEntryTransformer;
|
||||||
import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry;
|
import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry;
|
||||||
import org.gradle.api.Project;
|
|
||||||
import org.gradle.api.artifacts.Configuration;
|
|
||||||
import org.gradle.internal.impldep.aQute.lib.strings.Strings;
|
|
||||||
|
|
||||||
import net.fabricmc.loom.LoomGradleExtension;
|
import net.fabricmc.loom.LoomGradleExtension;
|
||||||
import net.fabricmc.loom.providers.MappingsProvider;
|
import net.fabricmc.loom.providers.MappingsProvider;
|
||||||
|
@ -110,7 +109,7 @@ public class ModProcessor {
|
||||||
JarEntry entry = parentJar.getJarEntry(fileName);
|
JarEntry entry = parentJar.getJarEntry(fileName);
|
||||||
|
|
||||||
if (entry == null) {
|
if (entry == null) {
|
||||||
throw new RuntimeException(Strings.format("%s was not found in %s", fileName, parentJar.getName()));
|
throw new RuntimeException(String.format("%s was not found in %s", fileName, parentJar.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
File nestedFile = new File(extension.getNestedModCache(), fileName.substring(fileName.lastIndexOf("/")));
|
File nestedFile = new File(extension.getNestedModCache(), fileName.substring(fileName.lastIndexOf("/")));
|
||||||
|
@ -133,7 +132,7 @@ public class ModProcessor {
|
||||||
|
|
||||||
private static void stripNestedJars(File file) {
|
private static void stripNestedJars(File file) {
|
||||||
//Strip out all contained jar info as we dont want loader to try and load the jars contained in dev.
|
//Strip out all contained jar info as we dont want loader to try and load the jars contained in dev.
|
||||||
ZipUtil.transformEntries(file, new ZipEntryTransformerEntry[]{(new ZipEntryTransformerEntry("fabric.mod.json", new StringZipEntryTransformer() {
|
ZipUtil.transformEntries(file, new ZipEntryTransformerEntry[] {(new ZipEntryTransformerEntry("fabric.mod.json", new StringZipEntryTransformer() {
|
||||||
@Override
|
@Override
|
||||||
protected String transform(ZipEntry zipEntry, String input) throws IOException {
|
protected String transform(ZipEntry zipEntry, String input) throws IOException {
|
||||||
JsonObject json = GSON.fromJson(input, JsonObject.class);
|
JsonObject json = GSON.fromJson(input, JsonObject.class);
|
||||||
|
@ -151,8 +150,6 @@ public class ModProcessor {
|
||||||
MinecraftMappedProvider mappedProvider = extension.getMinecraftMappedProvider();
|
MinecraftMappedProvider mappedProvider = extension.getMinecraftMappedProvider();
|
||||||
MappingsProvider mappingsProvider = extension.getMappingsProvider();
|
MappingsProvider mappingsProvider = extension.getMappingsProvider();
|
||||||
|
|
||||||
File mappingsFile = mappingsProvider.MAPPINGS_TINY;
|
|
||||||
Path mappings = mappingsFile.toPath();
|
|
||||||
Path inputPath = input.getAbsoluteFile().toPath();
|
Path inputPath = input.getAbsoluteFile().toPath();
|
||||||
Path mc = mappedProvider.MINECRAFT_INTERMEDIARY_JAR.toPath();
|
Path mc = mappedProvider.MINECRAFT_INTERMEDIARY_JAR.toPath();
|
||||||
Path[] mcDeps = mappedProvider.getMapperPaths().stream().map(File::toPath).toArray(Path[]::new);
|
Path[] mcDeps = mappedProvider.getMapperPaths().stream().map(File::toPath).toArray(Path[]::new);
|
||||||
|
@ -170,7 +167,9 @@ public class ModProcessor {
|
||||||
|
|
||||||
project.getLogger().lifecycle(":remapping " + input.getName() + " (TinyRemapper, " + fromM + " -> " + toM + ")");
|
project.getLogger().lifecycle(":remapping " + input.getName() + " (TinyRemapper, " + fromM + " -> " + toM + ")");
|
||||||
|
|
||||||
TinyRemapper remapper = TinyRemapper.newRemapper().withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM)).build();
|
TinyRemapper remapper = TinyRemapper.newRemapper()
|
||||||
|
.withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM, false))
|
||||||
|
.build();
|
||||||
|
|
||||||
try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(Paths.get(output.getAbsolutePath())).build()) {
|
try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(Paths.get(output.getAbsolutePath())).build()) {
|
||||||
outputConsumer.addNonClassFiles(inputPath);
|
outputConsumer.addNonClassFiles(inputPath);
|
||||||
|
|
|
@ -31,18 +31,18 @@ import java.nio.file.Path;
|
||||||
|
|
||||||
import org.cadixdev.lorenz.MappingSet;
|
import org.cadixdev.lorenz.MappingSet;
|
||||||
import org.cadixdev.lorenz.io.MappingsReader;
|
import org.cadixdev.lorenz.io.MappingsReader;
|
||||||
|
import org.cadixdev.lorenz.model.ClassMapping;
|
||||||
import org.cadixdev.mercury.Mercury;
|
import org.cadixdev.mercury.Mercury;
|
||||||
import org.cadixdev.mercury.remapper.MercuryRemapper;
|
import org.cadixdev.mercury.remapper.MercuryRemapper;
|
||||||
import org.zeroturnaround.zip.ZipUtil;
|
|
||||||
import org.gradle.api.Project;
|
import org.gradle.api.Project;
|
||||||
|
import org.zeroturnaround.zip.ZipUtil;
|
||||||
|
|
||||||
import net.fabricmc.loom.LoomGradleExtension;
|
import net.fabricmc.loom.LoomGradleExtension;
|
||||||
import net.fabricmc.loom.providers.MappingsProvider;
|
import net.fabricmc.loom.providers.MappingsProvider;
|
||||||
import net.fabricmc.mappings.ClassEntry;
|
import net.fabricmc.mapping.tree.ClassDef;
|
||||||
import net.fabricmc.mappings.EntryTriple;
|
import net.fabricmc.mapping.tree.FieldDef;
|
||||||
import net.fabricmc.mappings.FieldEntry;
|
import net.fabricmc.mapping.tree.MethodDef;
|
||||||
import net.fabricmc.mappings.Mappings;
|
import net.fabricmc.mapping.tree.TinyTree;
|
||||||
import net.fabricmc.mappings.MethodEntry;
|
|
||||||
import net.fabricmc.stitch.util.StitchUtil;
|
import net.fabricmc.stitch.util.StitchUtil;
|
||||||
|
|
||||||
public class SourceRemapper {
|
public class SourceRemapper {
|
||||||
|
@ -58,7 +58,7 @@ public class SourceRemapper {
|
||||||
|
|
||||||
MappingSet mappings = extension.getOrCreateSrcMappingCache(toNamed ? 1 : 0, () -> {
|
MappingSet mappings = extension.getOrCreateSrcMappingCache(toNamed ? 1 : 0, () -> {
|
||||||
try {
|
try {
|
||||||
Mappings m = mappingsProvider.getMappings();
|
TinyTree m = mappingsProvider.getMappings();
|
||||||
project.getLogger().lifecycle(":loading " + (toNamed ? "intermediary -> named" : "named -> intermediary") + " source mappings");
|
project.getLogger().lifecycle(":loading " + (toNamed ? "intermediary -> named" : "named -> intermediary") + " source mappings");
|
||||||
return new TinyReader(m, toNamed ? "intermediary" : "named", toNamed ? "named" : "intermediary").read();
|
return new TinyReader(m, toNamed ? "intermediary" : "named", toNamed ? "named" : "intermediary").read();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -69,17 +69,7 @@ public class SourceRemapper {
|
||||||
project.getLogger().info(":remapping source jar");
|
project.getLogger().info(":remapping source jar");
|
||||||
|
|
||||||
Mercury mercury = extension.getOrCreateSrcMercuryCache(toNamed ? 1 : 0, () -> {
|
Mercury mercury = extension.getOrCreateSrcMercuryCache(toNamed ? 1 : 0, () -> {
|
||||||
Mercury m = new Mercury();
|
Mercury m = createMercuryWithClassPath(project, toNamed);
|
||||||
|
|
||||||
for (File file : project.getConfigurations().getByName(Constants.MINECRAFT_DEPENDENCIES).getFiles()) {
|
|
||||||
m.getClassPath().add(file.toPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!toNamed) {
|
|
||||||
for (File file : project.getConfigurations().getByName("compileClasspath").getFiles()) {
|
|
||||||
m.getClassPath().add(file.toPath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Path file : extension.getUnmappedMods()) {
|
for (Path file : extension.getUnmappedMods()) {
|
||||||
if (Files.isRegularFile(file)) {
|
if (Files.isRegularFile(file)) {
|
||||||
|
@ -159,6 +149,22 @@ public class SourceRemapper {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Mercury createMercuryWithClassPath(Project project, boolean toNamed) {
|
||||||
|
Mercury m = new Mercury();
|
||||||
|
|
||||||
|
for (File file : project.getConfigurations().getByName(Constants.MINECRAFT_DEPENDENCIES).getFiles()) {
|
||||||
|
m.getClassPath().add(file.toPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!toNamed) {
|
||||||
|
for (File file : project.getConfigurations().getByName("compileClasspath").getFiles()) {
|
||||||
|
m.getClassPath().add(file.toPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isJavaFile(Path path) {
|
private static boolean isJavaFile(Path path) {
|
||||||
String name = path.getFileName().toString();
|
String name = path.getFileName().toString();
|
||||||
// ".java" is not a valid java file
|
// ".java" is not a valid java file
|
||||||
|
@ -166,39 +172,36 @@ public class SourceRemapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TinyReader extends MappingsReader {
|
public static class TinyReader extends MappingsReader {
|
||||||
private final Mappings m;
|
private final TinyTree mappings;
|
||||||
private final String from, to;
|
private final String from, to;
|
||||||
|
|
||||||
public TinyReader(Mappings m, String from, String to) {
|
public TinyReader(TinyTree m, String from, String to) {
|
||||||
this.m = m;
|
this.mappings = m;
|
||||||
this.from = from;
|
this.from = from;
|
||||||
this.to = to;
|
this.to = to;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MappingSet read(final MappingSet mappings) {
|
public MappingSet read(final MappingSet mappings) {
|
||||||
for (ClassEntry entry : m.getClassEntries()) {
|
for (ClassDef classDef : this.mappings.getClasses()) {
|
||||||
mappings.getOrCreateClassMapping(entry.get(from)).setDeobfuscatedName(entry.get(to));
|
ClassMapping classMapping = mappings.getOrCreateClassMapping(classDef.getName(from))
|
||||||
|
.setDeobfuscatedName(classDef.getName(to));
|
||||||
|
|
||||||
|
for (FieldDef field : classDef.getFields()) {
|
||||||
|
classMapping.getOrCreateFieldMapping(field.getName(from), field.getDescriptor(from))
|
||||||
|
.setDeobfuscatedName(field.getName(to));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (FieldEntry entry : m.getFieldEntries()) {
|
for (MethodDef method : classDef.getMethods()) {
|
||||||
EntryTriple fromEntry = entry.get(from);
|
classMapping.getOrCreateMethodMapping(method.getName(from), method.getDescriptor(from))
|
||||||
EntryTriple toEntry = entry.get(to);
|
.setDeobfuscatedName(method.getName(to));
|
||||||
|
|
||||||
mappings.getOrCreateClassMapping(fromEntry.getOwner()).getOrCreateFieldMapping(fromEntry.getName(), fromEntry.getDesc()).setDeobfuscatedName(toEntry.getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (MethodEntry entry : m.getMethodEntries()) {
|
|
||||||
EntryTriple fromEntry = entry.get(from);
|
|
||||||
EntryTriple toEntry = entry.get(to);
|
|
||||||
|
|
||||||
mappings.getOrCreateClassMapping(fromEntry.getOwner()).getOrCreateMethodMapping(fromEntry.getName(), fromEntry.getDesc()).setDeobfuscatedName(toEntry.getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mappings;
|
return mappings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException { }
|
public void close() { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,31 +24,47 @@
|
||||||
|
|
||||||
package net.fabricmc.loom.util;
|
package net.fabricmc.loom.util;
|
||||||
|
|
||||||
import net.fabricmc.mappings.ClassEntry;
|
import net.fabricmc.mapping.tree.ClassDef;
|
||||||
import net.fabricmc.mappings.EntryTriple;
|
import net.fabricmc.mapping.tree.FieldDef;
|
||||||
import net.fabricmc.mappings.FieldEntry;
|
import net.fabricmc.mapping.tree.LocalVariableDef;
|
||||||
import net.fabricmc.mappings.Mappings;
|
import net.fabricmc.mapping.tree.MethodDef;
|
||||||
import net.fabricmc.mappings.MethodEntry;
|
import net.fabricmc.mapping.tree.ParameterDef;
|
||||||
|
import net.fabricmc.mapping.tree.TinyTree;
|
||||||
import net.fabricmc.tinyremapper.IMappingProvider;
|
import net.fabricmc.tinyremapper.IMappingProvider;
|
||||||
import net.fabricmc.tinyremapper.MemberInstance;
|
|
||||||
|
|
||||||
public class TinyRemapperMappingsHelper {
|
public class TinyRemapperMappingsHelper {
|
||||||
private TinyRemapperMappingsHelper() { }
|
private TinyRemapperMappingsHelper() { }
|
||||||
|
|
||||||
public static IMappingProvider create(Mappings mappings, String from, String to) {
|
private static IMappingProvider.Member memberOf(String className, String memberName, String descriptor) {
|
||||||
return (classMap, fieldMap, methodMap) -> {
|
return new IMappingProvider.Member(className, memberName, descriptor);
|
||||||
for (ClassEntry entry : mappings.getClassEntries()) {
|
|
||||||
classMap.put(entry.get(from), entry.get(to));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (FieldEntry entry : mappings.getFieldEntries()) {
|
public static IMappingProvider create(TinyTree mappings, String from, String to, boolean remapLocalVariables) {
|
||||||
EntryTriple fromTriple = entry.get(from);
|
return (acceptor) -> {
|
||||||
fieldMap.put(fromTriple.getOwner() + "/" + MemberInstance.getFieldId(fromTriple.getName(), fromTriple.getDesc()), entry.get(to).getName());
|
for (ClassDef classDef : mappings.getClasses()) {
|
||||||
|
String className = classDef.getName(from);
|
||||||
|
acceptor.acceptClass(className, classDef.getName(to));
|
||||||
|
|
||||||
|
for (FieldDef field : classDef.getFields()) {
|
||||||
|
acceptor.acceptField(memberOf(className, field.getName(from), field.getDescriptor(from)), field.getName(to));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (MethodEntry entry : mappings.getMethodEntries()) {
|
for (MethodDef method : classDef.getMethods()) {
|
||||||
EntryTriple fromTriple = entry.get(from);
|
IMappingProvider.Member methodIdentifier = memberOf(className, method.getName(from), method.getDescriptor(from));
|
||||||
methodMap.put(fromTriple.getOwner() + "/" + MemberInstance.getMethodId(fromTriple.getName(), fromTriple.getDesc()), entry.get(to).getName());
|
acceptor.acceptMethod(methodIdentifier, method.getName(to));
|
||||||
|
|
||||||
|
if (remapLocalVariables) {
|
||||||
|
for (ParameterDef parameter : method.getParameters()) {
|
||||||
|
acceptor.acceptMethodArg(methodIdentifier, parameter.getLocalVariableIndex(), parameter.getName(to));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (LocalVariableDef localVariable : method.getLocalVariables()) {
|
||||||
|
acceptor.acceptMethodVar(methodIdentifier, localVariable.getLocalVariableIndex(),
|
||||||
|
localVariable.getLocalVariableStartOffset(), localVariable.getLocalVariableTableIndex(),
|
||||||
|
localVariable.getName(to));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ archivesBaseName = project.archives_base_name
|
||||||
version = project.mod_version
|
version = project.mod_version
|
||||||
group = project.maven_group
|
group = project.maven_group
|
||||||
|
|
||||||
|
|
||||||
minecraft {
|
minecraft {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ class EmptyBuildFunctionalTest extends Specification {
|
||||||
when:
|
when:
|
||||||
def result = GradleRunner.create()
|
def result = GradleRunner.create()
|
||||||
.withProjectDir(testProjectDir.root)
|
.withProjectDir(testProjectDir.root)
|
||||||
.withArguments('build')
|
.withArguments('build',"--stacktrace")
|
||||||
.withPluginClasspath()
|
.withPluginClasspath()
|
||||||
.withGradleVersion("4.9")
|
.withGradleVersion("4.9")
|
||||||
.build()
|
.build()
|
||||||
|
|
|
@ -45,9 +45,10 @@ class SimpleBuildFunctionalTest extends Specification {
|
||||||
when:
|
when:
|
||||||
def result = GradleRunner.create()
|
def result = GradleRunner.create()
|
||||||
.withProjectDir(testProjectDir.root)
|
.withProjectDir(testProjectDir.root)
|
||||||
.withArguments('build')
|
.withArguments('build',"--stacktrace")
|
||||||
.withPluginClasspath()
|
.withPluginClasspath()
|
||||||
.withGradleVersion("4.9")
|
.withGradleVersion("4.9")
|
||||||
|
.withDebug(true)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
then:
|
then:
|
||||||
|
@ -55,6 +56,7 @@ class SimpleBuildFunctionalTest extends Specification {
|
||||||
|
|
||||||
where:
|
where:
|
||||||
mcVersion | yarnVersion | loaderVersion | fabricVersion
|
mcVersion | yarnVersion | loaderVersion | fabricVersion
|
||||||
|
'19w45a' | '19w45a+build.2:v2' | '0.6.2+build.166' | '0.4.9+build.258-1.15'
|
||||||
'1.14' | '1.14+build.21' | '0.4.8+build.155' | '0.3.0+build.184'
|
'1.14' | '1.14+build.21' | '0.4.8+build.155' | '0.3.0+build.184'
|
||||||
'1.14.1' | '1.14.1+build.10' | '0.4.8+build.155' | '0.3.0+build.184'
|
'1.14.1' | '1.14.1+build.10' | '0.4.8+build.155' | '0.3.0+build.184'
|
||||||
'1.14.2' | '1.14.2+build.7' | '0.4.8+build.155' | '0.3.0+build.184'
|
'1.14.2' | '1.14.2+build.7' | '0.4.8+build.155' | '0.3.0+build.184'
|
||||||
|
|
Loading…
Reference in New Issue