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')
|
||||
|
||||
// game handling utils
|
||||
implementation ('net.fabricmc:stitch:0.2.1.60') {
|
||||
implementation ('net.fabricmc:stitch:0.3.0.66') {
|
||||
exclude module: 'enigma'
|
||||
}
|
||||
|
||||
// tinyfile management
|
||||
implementation ('net.fabricmc:tiny-remapper:0.1.0.38') {
|
||||
implementation ('net.fabricmc:tiny-remapper:0.2.0.52') {
|
||||
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
|
||||
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
|
||||
|
||||
project.getConfigurations().maybeCreate(Constants.MAPPINGS);
|
||||
project.getConfigurations().maybeCreate(Constants.MAPPINGS_FINAL);
|
||||
|
||||
for (RemappedConfigurationEntry entry : Constants.MOD_COMPILE_ENTRIES) {
|
||||
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_INTERMEDIARY, Constants.MINECRAFT_DEPENDENCIES);
|
||||
|
||||
extendsFrom("compile", Constants.MAPPINGS);
|
||||
extendsFrom("annotationProcessor", Constants.MAPPINGS);
|
||||
extendsFrom("compile", Constants.MAPPINGS_FINAL);
|
||||
extendsFrom("annotationProcessor", Constants.MAPPINGS_FINAL);
|
||||
|
||||
configureIDEs();
|
||||
configureCompile();
|
||||
|
@ -156,8 +157,8 @@ public class AbstractPlugin implements Plugin<Project> {
|
|||
project.getLogger().lifecycle(":setting java compiler args");
|
||||
|
||||
try {
|
||||
javaCompileTask.getOptions().getCompilerArgs().add("-AinMapFileNamedIntermediary=" + extension.getMappingsProvider().MAPPINGS_TINY.getCanonicalPath());
|
||||
javaCompileTask.getOptions().getCompilerArgs().add("-AoutMapFileNamedIntermediary=" + extension.getMappingsProvider().MAPPINGS_MIXIN_EXPORT.getCanonicalPath());
|
||||
javaCompileTask.getOptions().getCompilerArgs().add("-AinMapFileNamedIntermediary=" + extension.getMappingsProvider().tinyMappings.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("-AdefaultObfuscationEnv=named:intermediary");
|
||||
} catch (IOException e) {
|
||||
|
@ -183,8 +184,8 @@ public class AbstractPlugin implements Plugin<Project> {
|
|||
project.getLogger().warn(":configuring scala compilation processing");
|
||||
|
||||
try {
|
||||
task.getOptions().getCompilerArgs().add("-AinMapFileNamedIntermediary=" + extension.getMappingsProvider().MAPPINGS_TINY.getCanonicalPath());
|
||||
task.getOptions().getCompilerArgs().add("-AoutMapFileNamedIntermediary=" + extension.getMappingsProvider().MAPPINGS_MIXIN_EXPORT.getCanonicalPath());
|
||||
task.getOptions().getCompilerArgs().add("-AinMapFileNamedIntermediary=" + extension.getMappingsProvider().tinyMappings.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("-AdefaultObfuscationEnv=named:intermediary");
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
|
||||
package net.fabricmc.loom.providers;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
@ -33,32 +33,32 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
|
||||
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 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();
|
||||
|
||||
if (StaticPathWatcher.INSTANCE.hasFileChanged(mappingsPath)) {
|
||||
mappingsCache.remove(mappingsPath);
|
||||
}
|
||||
|
||||
SoftReference<Mappings> ref = mappingsCache.get(mappingsPath);
|
||||
SoftReference<TinyTree> ref = mappingsCache.get(mappingsPath);
|
||||
|
||||
if (ref != null && ref.get() != null) {
|
||||
return ref.get();
|
||||
} else {
|
||||
try (InputStream stream = Files.newInputStream(mappingsPath)) {
|
||||
Mappings mappings = net.fabricmc.mappings.MappingsProvider.readTinyMappings(stream, false);
|
||||
try (BufferedReader reader = Files.newBufferedReader(mappingsPath)) {
|
||||
TinyTree mappings = TinyMappingFactory.loadWithDetection(reader);
|
||||
ref = new SoftReference<>(mappings);
|
||||
mappingsCache.put(mappingsPath, ref);
|
||||
return mappings;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,25 +24,38 @@
|
|||
|
||||
package net.fabricmc.loom.providers;
|
||||
|
||||
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.net.UrlEscapers;
|
||||
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.util.Constants;
|
||||
import net.fabricmc.loom.util.DependencyProvider;
|
||||
import net.fabricmc.loom.util.DownloadUtil;
|
||||
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.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 MinecraftMappedProvider mappedProvider;
|
||||
|
||||
|
@ -50,13 +63,21 @@ public class MappingsProvider extends DependencyProvider {
|
|||
public String minecraftVersion;
|
||||
public String mappingsVersion;
|
||||
|
||||
public File MAPPINGS_DIR;
|
||||
public File MAPPINGS_TINY_BASE;
|
||||
public File MAPPINGS_TINY;
|
||||
public File MAPPINGS_MIXIN_EXPORT;
|
||||
private Path mappingsDir;
|
||||
private Path mappingsStepsDir;
|
||||
// The mappings that gradle gives us
|
||||
private Path baseTinyMappings;
|
||||
// The mappings we use in practice
|
||||
public File tinyMappings;
|
||||
public File tinyMappingsJar;
|
||||
public File mappingsMixinExport;
|
||||
|
||||
public Mappings getMappings() throws IOException {
|
||||
return MappingsCache.INSTANCE.get(MAPPINGS_TINY.toPath());
|
||||
public void clean() throws IOException {
|
||||
FileUtils.deleteDirectory(mappingsDir.toFile());
|
||||
}
|
||||
|
||||
public TinyTree getMappings() throws IOException {
|
||||
return MappingsCache.INSTANCE.get(tinyMappings.toPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -66,50 +87,166 @@ public class MappingsProvider extends DependencyProvider {
|
|||
project.getLogger().lifecycle(":setting up mappings (" + dependency.getDependency().getName() + " " + 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);
|
||||
this.minecraftVersion = mappingsVersion.getMinecraftVersion();
|
||||
this.mappingsVersion = mappingsVersion.getMappingsVersion();
|
||||
this.mappingsVersion = mappingsVersion.getMappingsVersion() + (isV2 ? "-v2" : "");
|
||||
|
||||
initFiles(project);
|
||||
|
||||
if (!MAPPINGS_DIR.exists()) {
|
||||
MAPPINGS_DIR.mkdir();
|
||||
Files.createDirectories(mappingsDir);
|
||||
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()) {
|
||||
if (!MAPPINGS_TINY_BASE.exists()) {
|
||||
project.getLogger().lifecycle(":extracting " + mappingsJar.getName());
|
||||
tinyMappings = mappingsDir.resolve(StringUtils.removeSuffix(mappingsJar.getName(), ".jar") + ".tiny").toFile();
|
||||
tinyMappingsJar = new File(extension.getUserCache(), mappingsJar.getName().replace(".jar", "-" + jarClassifier + ".jar"));
|
||||
|
||||
try (FileSystem fileSystem = FileSystems.newFileSystem(mappingsJar.toPath(), null)) {
|
||||
Path fileToExtract = fileSystem.getPath("mappings/mappings.tiny");
|
||||
Files.copy(fileToExtract, MAPPINGS_TINY_BASE.toPath());
|
||||
}
|
||||
if (!tinyMappings.exists()) {
|
||||
storeMappings(project, minecraftProvider, mappingsJar.toPath());
|
||||
}
|
||||
|
||||
if (MAPPINGS_TINY.exists()) {
|
||||
MAPPINGS_TINY.delete();
|
||||
if (!tinyMappingsJar.exists()) {
|
||||
ZipUtil.pack(new ZipEntrySource[] {new FileSource("mappings/mappings.tiny", tinyMappings)}, tinyMappingsJar);
|
||||
}
|
||||
|
||||
project.getLogger().lifecycle(":populating field names");
|
||||
new CommandProposeFieldNames().run(new String[]{minecraftProvider.MINECRAFT_MERGED_JAR.getAbsolutePath(), MAPPINGS_TINY_BASE.getAbsolutePath(), MAPPINGS_TINY.getAbsolutePath()});
|
||||
}
|
||||
addDependency(tinyMappingsJar, project, Constants.MAPPINGS_FINAL);
|
||||
|
||||
mappedProvider = new MinecraftMappedProvider();
|
||||
mappedProvider.initFiles(project, minecraftProvider, this);
|
||||
mappedProvider.provide(dependency, project, extension, postPopulationScheduler);
|
||||
}
|
||||
|
||||
public void initFiles(Project project) {
|
||||
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
||||
MAPPINGS_DIR = new File(extension.getUserCache(), "mappings");
|
||||
private void storeMappings(Project project, MinecraftProvider minecraftProvider, Path yarnJar) throws IOException {
|
||||
project.getLogger().lifecycle(":extracting " + yarnJar.getFileName());
|
||||
|
||||
MAPPINGS_TINY_BASE = new File(MAPPINGS_DIR, mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion + "-base");
|
||||
MAPPINGS_TINY = new File(MAPPINGS_DIR, mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion);
|
||||
MAPPINGS_MIXIN_EXPORT = new File(extension.getProjectBuildCache(), "mixin-map-" + minecraftVersion + "-" + mappingsVersion + ".tiny");
|
||||
try (FileSystem fileSystem = FileSystems.newFileSystem(yarnJar, null)) {
|
||||
extractMappings(fileSystem, baseTinyMappings);
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -39,11 +39,14 @@ public class MinecraftMappedProvider extends DependencyProvider {
|
|||
public File MINECRAFT_MAPPED_JAR;
|
||||
public File MINECRAFT_INTERMEDIARY_JAR;
|
||||
|
||||
public MinecraftMappedProvider() {
|
||||
}
|
||||
|
||||
private MinecraftProvider minecraftProvider;
|
||||
|
||||
@Override
|
||||
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");
|
||||
}
|
||||
|
||||
|
@ -67,17 +70,28 @@ public class MinecraftMappedProvider extends DependencyProvider {
|
|||
throw new RuntimeException("mapped jar not found");
|
||||
}
|
||||
|
||||
String version = minecraftProvider.minecraftVersion + "-mapped-" + extension.getMappingsProvider().mappingsName + "-" + extension.getMappingsProvider().mappingsVersion;
|
||||
project.getDependencies().add(Constants.MINECRAFT_NAMED, project.getDependencies().module("net.minecraft:minecraft:" + version));
|
||||
version = minecraftProvider.minecraftVersion + "-intermediary-" + extension.getMappingsProvider().mappingsName;
|
||||
project.getDependencies().add(Constants.MINECRAFT_INTERMEDIARY, project.getDependencies().module("net.minecraft:minecraft:" + version));
|
||||
MappingsProvider mappingsProvider = extension.getMappingsProvider();
|
||||
project.getDependencies().add(Constants.MINECRAFT_NAMED,
|
||||
project.getDependencies().module("net.minecraft:minecraft:" + getNamedJarVersionString(mappingsProvider.mappingsName, mappingsProvider.mappingsVersion)));
|
||||
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) {
|
||||
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
||||
this.minecraftProvider = minecraftProvider;
|
||||
MINECRAFT_INTERMEDIARY_JAR = new File(extension.getUserCache(), "minecraft-" + minecraftProvider.minecraftVersion + "-intermediary-" + mappingsProvider.mappingsName + ".jar");
|
||||
MINECRAFT_MAPPED_JAR = new File(extension.getUserCache(), "minecraft-" + minecraftProvider.minecraftVersion + "-mapped-" + mappingsProvider.mappingsName + "-" + mappingsProvider.mappingsVersion + ".jar");
|
||||
MINECRAFT_INTERMEDIARY_JAR = new File(extension.getUserCache(),
|
||||
"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() {
|
||||
|
|
|
@ -36,14 +36,12 @@ import net.fabricmc.loom.util.DeletingFileVisitor;
|
|||
public class CleanLoomMappings extends AbstractLoomTask {
|
||||
@TaskAction
|
||||
public void run() {
|
||||
try {
|
||||
Project project = this.getProject();
|
||||
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
||||
extension.getMappingsProvider().MAPPINGS_TINY.delete();
|
||||
extension.getMappingsProvider().MAPPINGS_TINY_BASE.delete();
|
||||
extension.getMappingsProvider().clean();
|
||||
extension.getMinecraftMappedProvider().getIntermediaryJar().delete();
|
||||
extension.getMinecraftMappedProvider().getMappedJar().delete();
|
||||
|
||||
try {
|
||||
Files.walkFileTree(extension.getRootProjectBuildCache().toPath(), new DeletingFileVisitor());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
|
|
|
@ -24,27 +24,41 @@
|
|||
|
||||
package net.fabricmc.loom.task;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
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.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.io.MappingsReader;
|
||||
import org.cadixdev.lorenz.model.ClassMapping;
|
||||
import org.cadixdev.lorenz.model.Mapping;
|
||||
import org.cadixdev.mercury.Mercury;
|
||||
import org.cadixdev.mercury.remapper.MercuryRemapper;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.loom.util.Version;
|
||||
import net.fabricmc.mappings.ClassEntry;
|
||||
import net.fabricmc.mappings.EntryTriple;
|
||||
import net.fabricmc.mappings.FieldEntry;
|
||||
import net.fabricmc.mappings.Mappings;
|
||||
import net.fabricmc.mappings.MethodEntry;
|
||||
import net.fabricmc.loom.providers.MappingsProvider;
|
||||
import net.fabricmc.loom.providers.MinecraftMappedProvider;
|
||||
import net.fabricmc.loom.util.SourceRemapper;
|
||||
import net.fabricmc.mapping.tree.ClassDef;
|
||||
import net.fabricmc.mapping.tree.Descriptored;
|
||||
import net.fabricmc.mapping.tree.FieldDef;
|
||||
import net.fabricmc.mapping.tree.MethodDef;
|
||||
import net.fabricmc.mapping.tree.TinyMappingFactory;
|
||||
import net.fabricmc.mapping.tree.TinyTree;
|
||||
|
||||
public class MigrateMappingsTask extends AbstractLoomTask {
|
||||
@TaskAction
|
||||
|
@ -55,75 +69,95 @@ public class MigrateMappingsTask extends AbstractLoomTask {
|
|||
|
||||
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")) {
|
||||
mappingsFile = new File((String) properties.get("targetMappingsFile"));
|
||||
} else if (properties.containsKey("targetMappingsArtifact")) {
|
||||
String[] artifactName = ((String) properties.get("targetMappingsArtifact")).split(":");
|
||||
|
||||
if (artifactName.length != 3) {
|
||||
throw new RuntimeException("Invalid artifact name: " + properties.get("targetMappingsArtifact"));
|
||||
if (officialMappingsVersion != null && localMappingsPath != null) {
|
||||
throw new IllegalArgumentException("targetMappings and targetLocalMappings are mutually exclusive;"
|
||||
+ " you either specify an official yarn mappings version with targetMappings, "
|
||||
+ "or a local one with targetLocalMappings.");
|
||||
}
|
||||
|
||||
String mappingsName = artifactName[0] + "." + artifactName[1];
|
||||
|
||||
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 (officialMappingsVersion == null && localMappingsPath == null) {
|
||||
throw new IllegalArgumentException("You must specify a new mappings version with -PtargetMappings (or local mappings with -PtargetLocalMappings).");
|
||||
}
|
||||
|
||||
if (mappingsFile == null || !mappingsFile.exists()) {
|
||||
throw new RuntimeException("Could not find mappings file: " + (mappingsFile != null ? mappingsFile : "null"));
|
||||
boolean useLocalMappings = localMappingsPath != 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")) {
|
||||
throw new RuntimeException("Must specify input and output dir!");
|
||||
String targetMappingsName = useLocalMappings ? localMappingsPath : officialMappingsVersion;
|
||||
|
||||
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"));
|
||||
File outputDir = new File((String) properties.get("outputDir"));
|
||||
Files.createDirectories(outputDirPath);
|
||||
|
||||
if (!inputDir.exists() || !inputDir.isDirectory()) {
|
||||
throw new RuntimeException("Could not find input directory: " + inputDir);
|
||||
}
|
||||
MappingsProvider mappingsProvider = extension.getMappingsProvider();
|
||||
|
||||
if (!outputDir.exists()) {
|
||||
if (!outputDir.mkdirs()) {
|
||||
throw new RuntimeException("Could not create output directory:" + outputDir);
|
||||
try {
|
||||
TinyTree currentMappings = mappingsProvider.getMappings();
|
||||
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();
|
||||
Mappings targetMappings;
|
||||
private TinyTree getMappings(Project project, String mappingsVersionOrPath, boolean useLocalMappings) throws IOException {
|
||||
Path migrateMappingsDir = Files.createTempDirectory("migrate");
|
||||
Path localMappingsOfVersion = migrateMappingsDir.resolve(mappingsVersionOrPath + ".tiny");
|
||||
|
||||
try (FileInputStream stream = new FileInputStream(mappingsFile)) {
|
||||
targetMappings = net.fabricmc.mappings.MappingsProvider.readTinyMappings(stream, false);
|
||||
if (!Files.exists(localMappingsOfVersion)) {
|
||||
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");
|
||||
MappingSet mappingSet = new MappingsJoiner(sourceMappings, targetMappings, "intermediary", "named").read();
|
||||
MappingSet mappingSet = new MappingsJoiner(currentMappings, targetMappings,
|
||||
"intermediary", "named").read();
|
||||
|
||||
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(file.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.getClassPath().add(minecraftMappedProvider.MINECRAFT_MAPPED_JAR.toPath());
|
||||
mercury.getClassPath().add(minecraftMappedProvider.MINECRAFT_INTERMEDIARY_JAR.toPath());
|
||||
|
||||
mercury.getProcessors().add(MercuryRemapper.create(mappingSet));
|
||||
|
||||
try {
|
||||
mercury.rewrite(inputDir.toPath(), outputDir.toPath());
|
||||
mercury.rewrite(inputDir, outputDir);
|
||||
} catch (Exception e) {
|
||||
project.getLogger().warn("Could not remap fully!", e);
|
||||
}
|
||||
|
@ -133,10 +167,19 @@ public class MigrateMappingsTask extends AbstractLoomTask {
|
|||
}
|
||||
|
||||
public static class MappingsJoiner extends MappingsReader {
|
||||
private final Mappings sourceMappings, targetMappings;
|
||||
private final TinyTree sourceMappings, targetMappings;
|
||||
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.targetMappings = targetMappings;
|
||||
this.fromNamespace = fromNamespace;
|
||||
|
@ -144,40 +187,51 @@ public class MigrateMappingsTask extends AbstractLoomTask {
|
|||
}
|
||||
|
||||
@Override
|
||||
public MappingSet read(MappingSet mappings) throws IOException {
|
||||
Map<String, ClassEntry> targetClasses = new HashMap<>();
|
||||
Map<EntryTriple, FieldEntry> targetFields = new HashMap<>();
|
||||
Map<EntryTriple, MethodEntry> targetMethods = new HashMap<>();
|
||||
public MappingSet read(MappingSet mappings) {
|
||||
Map<String, ClassDef> targetClasses = new HashMap<>();
|
||||
Map<String, FieldDef> targetFields = new HashMap<>();
|
||||
Map<String, MethodDef> targetMethods = new HashMap<>();
|
||||
|
||||
targetMappings.getClassEntries().forEach((c) -> targetClasses.put(c.get(fromNamespace), c));
|
||||
targetMappings.getFieldEntries().forEach((c) -> targetFields.put(c.get(fromNamespace), c));
|
||||
targetMappings.getMethodEntries().forEach((c) -> targetMethods.put(c.get(fromNamespace), c));
|
||||
for (ClassDef newClass : targetMappings.getClasses()) {
|
||||
targetClasses.put(newClass.getName(fromNamespace), newClass);
|
||||
|
||||
for (ClassEntry entry : sourceMappings.getClassEntries()) {
|
||||
String from = entry.get(toNamespace);
|
||||
String to = targetClasses.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace);
|
||||
|
||||
mappings.getOrCreateClassMapping(from).setDeobfuscatedName(to);
|
||||
for (FieldDef field : newClass.getFields()) {
|
||||
targetFields.put(field.getName(fromNamespace), field);
|
||||
}
|
||||
|
||||
for (FieldEntry entry : sourceMappings.getFieldEntries()) {
|
||||
EntryTriple fromEntry = entry.get(toNamespace);
|
||||
EntryTriple toEntry = targetFields.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace);
|
||||
|
||||
mappings.getOrCreateClassMapping(fromEntry.getOwner()).getOrCreateFieldMapping(fromEntry.getName(), fromEntry.getDesc()).setDeobfuscatedName(toEntry.getName());
|
||||
for (MethodDef method : newClass.getMethods()) {
|
||||
targetMethods.put(method.getName(fromNamespace), method);
|
||||
}
|
||||
}
|
||||
|
||||
for (MethodEntry entry : sourceMappings.getMethodEntries()) {
|
||||
EntryTriple fromEntry = entry.get(toNamespace);
|
||||
EntryTriple toEntry = targetMethods.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace);
|
||||
for (ClassDef oldClass : sourceMappings.getClasses()) {
|
||||
String namedMappingOfSourceMapping = oldClass.getName(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;
|
||||
}
|
||||
|
||||
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
|
||||
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);
|
||||
|
||||
File mixinMapFile = mappingsProvider.MAPPINGS_MIXIN_EXPORT;
|
||||
File mixinMapFile = mappingsProvider.mappingsMixinExport;
|
||||
Path mixinMapPath = mixinMapFile.toPath();
|
||||
|
||||
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()) {
|
||||
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_LINEMAPPED = "minecraftLinemapped";
|
||||
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 + ")");
|
||||
|
||||
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()) {
|
||||
outputConsumer.addNonClassFiles(input);
|
||||
|
@ -64,7 +68,7 @@ public class MapJarsTiny {
|
|||
remapper.readInputs(input);
|
||||
remapper.apply(outputConsumer);
|
||||
} 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 {
|
||||
remapper.finish();
|
||||
}
|
||||
|
|
|
@ -41,13 +41,12 @@ import com.google.gson.Gson;
|
|||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
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.commons.FileUtils;
|
||||
import org.zeroturnaround.zip.transform.StringZipEntryTransformer;
|
||||
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.providers.MappingsProvider;
|
||||
|
@ -110,7 +109,7 @@ public class ModProcessor {
|
|||
JarEntry entry = parentJar.getJarEntry(fileName);
|
||||
|
||||
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("/")));
|
||||
|
@ -133,7 +132,7 @@ public class ModProcessor {
|
|||
|
||||
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.
|
||||
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
|
||||
protected String transform(ZipEntry zipEntry, String input) throws IOException {
|
||||
JsonObject json = GSON.fromJson(input, JsonObject.class);
|
||||
|
@ -151,8 +150,6 @@ public class ModProcessor {
|
|||
MinecraftMappedProvider mappedProvider = extension.getMinecraftMappedProvider();
|
||||
MappingsProvider mappingsProvider = extension.getMappingsProvider();
|
||||
|
||||
File mappingsFile = mappingsProvider.MAPPINGS_TINY;
|
||||
Path mappings = mappingsFile.toPath();
|
||||
Path inputPath = input.getAbsoluteFile().toPath();
|
||||
Path mc = mappedProvider.MINECRAFT_INTERMEDIARY_JAR.toPath();
|
||||
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 + ")");
|
||||
|
||||
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()) {
|
||||
outputConsumer.addNonClassFiles(inputPath);
|
||||
|
|
|
@ -31,18 +31,18 @@ import java.nio.file.Path;
|
|||
|
||||
import org.cadixdev.lorenz.MappingSet;
|
||||
import org.cadixdev.lorenz.io.MappingsReader;
|
||||
import org.cadixdev.lorenz.model.ClassMapping;
|
||||
import org.cadixdev.mercury.Mercury;
|
||||
import org.cadixdev.mercury.remapper.MercuryRemapper;
|
||||
import org.zeroturnaround.zip.ZipUtil;
|
||||
import org.gradle.api.Project;
|
||||
import org.zeroturnaround.zip.ZipUtil;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.providers.MappingsProvider;
|
||||
import net.fabricmc.mappings.ClassEntry;
|
||||
import net.fabricmc.mappings.EntryTriple;
|
||||
import net.fabricmc.mappings.FieldEntry;
|
||||
import net.fabricmc.mappings.Mappings;
|
||||
import net.fabricmc.mappings.MethodEntry;
|
||||
import net.fabricmc.mapping.tree.ClassDef;
|
||||
import net.fabricmc.mapping.tree.FieldDef;
|
||||
import net.fabricmc.mapping.tree.MethodDef;
|
||||
import net.fabricmc.mapping.tree.TinyTree;
|
||||
import net.fabricmc.stitch.util.StitchUtil;
|
||||
|
||||
public class SourceRemapper {
|
||||
|
@ -58,7 +58,7 @@ public class SourceRemapper {
|
|||
|
||||
MappingSet mappings = extension.getOrCreateSrcMappingCache(toNamed ? 1 : 0, () -> {
|
||||
try {
|
||||
Mappings m = mappingsProvider.getMappings();
|
||||
TinyTree m = mappingsProvider.getMappings();
|
||||
project.getLogger().lifecycle(":loading " + (toNamed ? "intermediary -> named" : "named -> intermediary") + " source mappings");
|
||||
return new TinyReader(m, toNamed ? "intermediary" : "named", toNamed ? "named" : "intermediary").read();
|
||||
} catch (Exception e) {
|
||||
|
@ -69,17 +69,7 @@ public class SourceRemapper {
|
|||
project.getLogger().info(":remapping source jar");
|
||||
|
||||
Mercury mercury = extension.getOrCreateSrcMercuryCache(toNamed ? 1 : 0, () -> {
|
||||
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());
|
||||
}
|
||||
}
|
||||
Mercury m = createMercuryWithClassPath(project, toNamed);
|
||||
|
||||
for (Path file : extension.getUnmappedMods()) {
|
||||
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) {
|
||||
String name = path.getFileName().toString();
|
||||
// ".java" is not a valid java file
|
||||
|
@ -166,39 +172,36 @@ public class SourceRemapper {
|
|||
}
|
||||
|
||||
public static class TinyReader extends MappingsReader {
|
||||
private final Mappings m;
|
||||
private final TinyTree mappings;
|
||||
private final String from, to;
|
||||
|
||||
public TinyReader(Mappings m, String from, String to) {
|
||||
this.m = m;
|
||||
public TinyReader(TinyTree m, String from, String to) {
|
||||
this.mappings = m;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappingSet read(final MappingSet mappings) {
|
||||
for (ClassEntry entry : m.getClassEntries()) {
|
||||
mappings.getOrCreateClassMapping(entry.get(from)).setDeobfuscatedName(entry.get(to));
|
||||
for (ClassDef classDef : this.mappings.getClasses()) {
|
||||
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()) {
|
||||
EntryTriple fromEntry = entry.get(from);
|
||||
EntryTriple toEntry = entry.get(to);
|
||||
|
||||
mappings.getOrCreateClassMapping(fromEntry.getOwner()).getOrCreateFieldMapping(fromEntry.getName(), fromEntry.getDesc()).setDeobfuscatedName(toEntry.getName());
|
||||
for (MethodDef method : classDef.getMethods()) {
|
||||
classMapping.getOrCreateMethodMapping(method.getName(from), method.getDescriptor(from))
|
||||
.setDeobfuscatedName(method.getName(to));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException { }
|
||||
public void close() { }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,31 +24,47 @@
|
|||
|
||||
package net.fabricmc.loom.util;
|
||||
|
||||
import net.fabricmc.mappings.ClassEntry;
|
||||
import net.fabricmc.mappings.EntryTriple;
|
||||
import net.fabricmc.mappings.FieldEntry;
|
||||
import net.fabricmc.mappings.Mappings;
|
||||
import net.fabricmc.mappings.MethodEntry;
|
||||
import net.fabricmc.mapping.tree.ClassDef;
|
||||
import net.fabricmc.mapping.tree.FieldDef;
|
||||
import net.fabricmc.mapping.tree.LocalVariableDef;
|
||||
import net.fabricmc.mapping.tree.MethodDef;
|
||||
import net.fabricmc.mapping.tree.ParameterDef;
|
||||
import net.fabricmc.mapping.tree.TinyTree;
|
||||
import net.fabricmc.tinyremapper.IMappingProvider;
|
||||
import net.fabricmc.tinyremapper.MemberInstance;
|
||||
|
||||
public class TinyRemapperMappingsHelper {
|
||||
private TinyRemapperMappingsHelper() { }
|
||||
|
||||
public static IMappingProvider create(Mappings mappings, String from, String to) {
|
||||
return (classMap, fieldMap, methodMap) -> {
|
||||
for (ClassEntry entry : mappings.getClassEntries()) {
|
||||
classMap.put(entry.get(from), entry.get(to));
|
||||
private static IMappingProvider.Member memberOf(String className, String memberName, String descriptor) {
|
||||
return new IMappingProvider.Member(className, memberName, descriptor);
|
||||
}
|
||||
|
||||
for (FieldEntry entry : mappings.getFieldEntries()) {
|
||||
EntryTriple fromTriple = entry.get(from);
|
||||
fieldMap.put(fromTriple.getOwner() + "/" + MemberInstance.getFieldId(fromTriple.getName(), fromTriple.getDesc()), entry.get(to).getName());
|
||||
public static IMappingProvider create(TinyTree mappings, String from, String to, boolean remapLocalVariables) {
|
||||
return (acceptor) -> {
|
||||
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()) {
|
||||
EntryTriple fromTriple = entry.get(from);
|
||||
methodMap.put(fromTriple.getOwner() + "/" + MemberInstance.getMethodId(fromTriple.getName(), fromTriple.getDesc()), entry.get(to).getName());
|
||||
for (MethodDef method : classDef.getMethods()) {
|
||||
IMappingProvider.Member methodIdentifier = memberOf(className, method.getName(from), method.getDescriptor(from));
|
||||
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
|
||||
group = project.maven_group
|
||||
|
||||
|
||||
minecraft {
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ class EmptyBuildFunctionalTest extends Specification {
|
|||
when:
|
||||
def result = GradleRunner.create()
|
||||
.withProjectDir(testProjectDir.root)
|
||||
.withArguments('build')
|
||||
.withArguments('build',"--stacktrace")
|
||||
.withPluginClasspath()
|
||||
.withGradleVersion("4.9")
|
||||
.build()
|
||||
|
|
|
@ -45,9 +45,10 @@ class SimpleBuildFunctionalTest extends Specification {
|
|||
when:
|
||||
def result = GradleRunner.create()
|
||||
.withProjectDir(testProjectDir.root)
|
||||
.withArguments('build')
|
||||
.withArguments('build',"--stacktrace")
|
||||
.withPluginClasspath()
|
||||
.withGradleVersion("4.9")
|
||||
.withDebug(true)
|
||||
.build()
|
||||
|
||||
then:
|
||||
|
@ -55,6 +56,7 @@ class SimpleBuildFunctionalTest extends Specification {
|
|||
|
||||
where:
|
||||
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' | '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'
|
||||
|
|
Loading…
Reference in New Issue