From f85daec55951afbfebef734e2ad10475166c9205 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Sat, 2 Nov 2019 20:23:27 +0000 Subject: [PATCH] Reformat to use Fabric API's checkstyle (#137) * Reformat to use Fabric API's checkstyle * Fix * Fix * Update * Travis and fixes * possible fix for checkstyle? * Helps if i push the checkstyle.xml file... * Log checkstyle issues to console - used by travis * Fix some more issues * opps --- .gitignore | 4 +- .travis.yml | 12 + build.gradle | 16 ++ checkstyle.xml | 162 ++++++++++++ .../net/fabricmc/loom/AbstractPlugin.java | 112 +++++---- .../fabricmc/loom/LoomGradleExtension.java | 96 ++++--- .../net/fabricmc/loom/LoomGradlePlugin.java | 31 ++- .../loom/providers/MappingsCache.java | 55 ++-- .../loom/providers/MappingsProvider.java | 28 +-- .../providers/MinecraftAssetsProvider.java | 27 +- .../providers/MinecraftLibraryProvider.java | 23 +- .../providers/MinecraftMappedProvider.java | 109 ++++---- .../providers/MinecraftNativesProvider.java | 16 +- .../loom/providers/MinecraftProvider.java | 63 ++--- .../loom/task/AbstractDecompileTask.java | 59 +++-- .../fabricmc/loom/task/AbstractLoomTask.java | 2 - .../fabricmc/loom/task/AbstractRunTask.java | 186 +++++++------- .../fabricmc/loom/task/CleanLoomBinaries.java | 34 +-- .../fabricmc/loom/task/CleanLoomMappings.java | 40 +-- .../loom/task/DownloadAssetsTask.java | 9 +- .../loom/task/ForkingJavaExecTask.java | 22 +- .../loom/task/GenEclipseRunsTask.java | 42 ++-- .../loom/task/GenIdeaProjectTask.java | 32 ++- .../loom/task/GenVsCodeProjectTask.java | 118 ++++----- .../loom/task/MigrateMappingsTask.java | 226 ++++++++--------- .../net/fabricmc/loom/task/RemapJarTask.java | 33 +-- .../loom/task/RemapLineNumbersTask.java | 85 ++++--- .../loom/task/RemapSourcesJarTask.java | 38 ++- .../loom/task/fernflower/FernFlowerTask.java | 199 ++++++++------- .../loom/task/fernflower/FernFlowerUtils.java | 31 +-- .../task/fernflower/ForkedFFExecutor.java | 130 +++++----- .../loom/task/fernflower/NoopFFLogger.java | 13 +- .../task/fernflower/ThreadIDFFLogger.java | 156 ++++++------ .../fernflower/ThreadSafeResultSaver.java | 224 +++++++++-------- .../java/net/fabricmc/loom/util/Checksum.java | 10 +- .../net/fabricmc/loom/util/Constants.java | 14 +- .../loom/util/ConsumingOutputStream.java | 51 ++-- .../loom/util/DependencyProvider.java | 64 +++-- .../net/fabricmc/loom/util/DownloadUtil.java | 68 +++-- .../net/fabricmc/loom/util/GradleSupport.java | 14 +- .../net/fabricmc/loom/util/GroovyXmlUtil.java | 8 +- .../loom/util/LineNumberRemapper.java | 238 ++++++++++-------- .../loom/util/LoomDependencyManager.java | 58 +++-- .../net/fabricmc/loom/util/MapJarsTiny.java | 30 +-- .../loom/util/MinecraftVersionInfo.java | 30 ++- .../fabricmc/loom/util/MixinRefmapHelper.java | 160 ++++++------ .../loom/util/ModCompileRemapper.java | 23 +- .../net/fabricmc/loom/util/ModProcessor.java | 100 ++++---- .../net/fabricmc/loom/util/NestedJars.java | 73 +++--- .../fabricmc/loom/util/OperatingSystem.java | 1 + .../loom/util/RemappedConfigurationEntry.java | 62 ++--- .../net/fabricmc/loom/util/RunConfig.java | 74 +++--- .../loom/util/SetupIntelijRunConfigs.java | 32 +-- .../fabricmc/loom/util/SourceRemapper.java | 89 +++---- .../fabricmc/loom/util/StaticPathWatcher.java | 101 ++++---- .../loom/util/TinyRemapperMappingsHelper.java | 10 +- .../java/net/fabricmc/loom/util/Version.java | 5 +- .../loom/util/assets/AssetObject.java | 2 +- .../loom/util/progress/ProgressLogger.java | 34 +-- 59 files changed, 2129 insertions(+), 1655 deletions(-) create mode 100644 .travis.yml create mode 100644 checkstyle.xml diff --git a/.gitignore b/.gitignore index 198da20..beb2556 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,6 @@ !/LICENSE !/README.md !/settings.gradle -!/Jenkinsfile \ No newline at end of file +!/Jenkinsfile +!/.travis.yml +!/checkstyle.xml \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..ad00567 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,12 @@ +language: java +install: true + +jdk: + - openjdk8 + +script: + - chmod +x gradlew + - ./gradlew check build test --stacktrace + +notifications: + email: false \ No newline at end of file diff --git a/build.gradle b/build.gradle index dae48d8..90fe3c3 100644 --- a/build.gradle +++ b/build.gradle @@ -5,6 +5,7 @@ plugins { id 'idea' id 'eclipse' id 'groovy' + id 'checkstyle' } sourceCompatibility = 1.8 @@ -60,6 +61,12 @@ dependencies { testImplementation("org.spockframework:spock-core:1.3-groovy-2.4") } +configurations.all { + resolutionStrategy { + force 'org.codehaus.groovy:groovy-all:2.4.12' + } +} + jar { manifest { attributes 'Implementation-Version': version + " Build(" + build + ")" @@ -82,6 +89,15 @@ license { exclude '**/loom/util/DownloadUtil.java' } +checkstyle { + configFile = file("checkstyle.xml") + toolVersion = '8.25' +} + +checkstyleMain { + logging.setLevel(LogLevel.LIFECYCLE) +} + gradlePlugin { plugins { fabricLoom { diff --git a/checkstyle.xml b/checkstyle.xml new file mode 100644 index 0000000..341ddb1 --- /dev/null +++ b/checkstyle.xml @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/net/fabricmc/loom/AbstractPlugin.java b/src/main/java/net/fabricmc/loom/AbstractPlugin.java index bafce6e..ceb31bd 100644 --- a/src/main/java/net/fabricmc/loom/AbstractPlugin.java +++ b/src/main/java/net/fabricmc/loom/AbstractPlugin.java @@ -24,13 +24,16 @@ package net.fabricmc.loom; +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.Predicate; + import com.google.common.collect.ImmutableMap; import groovy.util.Node; -import net.fabricmc.loom.providers.MappingsProvider; -import net.fabricmc.loom.providers.MinecraftProvider; -import net.fabricmc.loom.task.RemapJarTask; -import net.fabricmc.loom.task.RemapSourcesJarTask; -import net.fabricmc.loom.util.*; import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.Task; @@ -54,13 +57,16 @@ import org.gradle.api.tasks.scala.ScalaCompile; import org.gradle.plugins.ide.eclipse.model.EclipseModel; import org.gradle.plugins.ide.idea.model.IdeaModel; -import java.io.File; -import java.io.IOException; -import java.util.HashSet; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.function.Predicate; +import net.fabricmc.loom.providers.MappingsProvider; +import net.fabricmc.loom.providers.MinecraftProvider; +import net.fabricmc.loom.task.RemapJarTask; +import net.fabricmc.loom.task.RemapSourcesJarTask; +import net.fabricmc.loom.util.Constants; +import net.fabricmc.loom.util.GroovyXmlUtil; +import net.fabricmc.loom.util.LoomDependencyManager; +import net.fabricmc.loom.util.NestedJars; +import net.fabricmc.loom.util.RemappedConfigurationEntry; +import net.fabricmc.loom.util.SetupIntelijRunConfigs; public class AbstractPlugin implements Plugin { protected Project project; @@ -116,6 +122,7 @@ public class AbstractPlugin implements Plugin { compileModsMappedConfig.setTransitive(false); // Don't get transitive deps of already remapped mods extendsFrom(entry.getTargetConfiguration(project.getConfigurations()), entry.getRemappedConfiguration()); + if (entry.isOnModCompileClasspath()) { extendsFrom(Constants.MOD_COMPILE_CLASSPATH, entry.getSourceConfiguration()); extendsFrom(Constants.MOD_COMPILE_CLASSPATH_MAPPED, entry.getRemappedConfiguration()); @@ -137,15 +144,17 @@ public class AbstractPlugin implements Plugin { configureScala(); Map> taskMap = project.getAllTasks(true); + for (Map.Entry> entry : taskMap.entrySet()) { Project project = entry.getKey(); Set taskSet = entry.getValue(); + for (Task task : taskSet) { - if (task instanceof JavaCompile - && !(task.getName().contains("Test")) && !(task.getName().contains("test"))) { + if (task instanceof JavaCompile && !(task.getName().contains("Test")) && !(task.getName().contains("test"))) { JavaCompile javaCompileTask = (JavaCompile) task; javaCompileTask.doFirst(task1 -> { 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()); @@ -166,30 +175,31 @@ public class AbstractPlugin implements Plugin { return project; } - protected void configureScala() { - project.afterEvaluate(proj -> { - if (project.getPluginManager().hasPlugin("scala")) { - ScalaCompile task = (ScalaCompile) project.getTasks().getByName("compileScala"); - LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); - 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("-AoutRefMapFile=" + new File(task.getDestinationDir(), extension.getRefmapName()).getCanonicalPath()); - task.getOptions().getCompilerArgs().add("-AdefaultObfuscationEnv=named:intermediary"); - } catch (IOException e) { - e.printStackTrace(); - } - } - }); - } + protected void configureScala() { + project.afterEvaluate(proj -> { + if (project.getPluginManager().hasPlugin("scala")) { + ScalaCompile task = (ScalaCompile) project.getTasks().getByName("compileScala"); + LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); + 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("-AoutRefMapFile=" + new File(task.getDestinationDir(), extension.getRefmapName()).getCanonicalPath()); + task.getOptions().getCompilerArgs().add("-AdefaultObfuscationEnv=named:intermediary"); + } catch (IOException e) { + e.printStackTrace(); + } + } + }); + } /** - * Permit to add a Maven repository to a target project + * Permit to add a Maven repository to a target project. * * @param target The garget project - * @param name The name of the repository - * @param url The URL of the repository + * @param name The name of the repository + * @param url The URL of the repository * @return An object containing the name and the URL of the repository that can be modified later */ public MavenArtifactRepository addMavenRepo(Project target, final String name, final String url) { @@ -200,7 +210,7 @@ public class AbstractPlugin implements Plugin { } /** - * Add Minecraft dependencies to IDE dependencies + * Add Minecraft dependencies to IDE dependencies. */ protected void configureIDEs() { // IDEA @@ -236,6 +246,7 @@ public class AbstractPlugin implements Plugin { if (dep instanceof ResolvedDependencyResult) { if (dep.getFrom().getId() instanceof ModuleComponentIdentifier) { ModuleComponentIdentifier mci = ((ModuleComponentIdentifier) dep.getFrom().getId()); + if (predicate.test(mci)) { addModule(project, configuration, dep); found = true; @@ -251,7 +262,7 @@ public class AbstractPlugin implements Plugin { } /** - * Add Minecraft dependencies to compile time + * Add Minecraft dependencies to compile time. */ protected void configureCompile() { JavaPluginConvention javaModule = (JavaPluginConvention) project.getConvention().getPlugins().get("java"); @@ -264,12 +275,18 @@ public class AbstractPlugin implements Plugin { // Add Mixin dependencies Project p = project; + while (true) { boolean found = false; + for (DependencyResult dep : p.getBuildscript().getConfigurations().getByName("classpath").getIncoming().getResolutionResult().getRoot().getDependencies()) { found = findAndAddModule(project, "annotationProcessor", dep, (mci) -> ("net.fabricmc".equals(mci.getGroup()) && "fabric-mixin-compile-extensions".equals(mci.getModule()))); } - if (found || AbstractPlugin.isRootProject(p)) break; + + if (found || AbstractPlugin.isRootProject(p)) { + break; + } + p = p.getRootProject(); } @@ -330,6 +347,7 @@ public class AbstractPlugin implements Plugin { RemapJarTask remapJarTask = (RemapJarTask) project1.getTasks().findByName("remapJar"); assert remapJarTask != null; + if (!remapJarTask.getInput().isPresent()) { jarTask.setClassifier("dev"); remapJarTask.setClassifier(""); @@ -344,8 +362,10 @@ public class AbstractPlugin implements Plugin { project1.getTasks().getByName("build").dependsOn(remapJarTask); Map> taskMap = project.getAllTasks(true); + for (Map.Entry> entry : taskMap.entrySet()) { Set taskSet = entry.getValue(); + for (Task task : taskSet) { if (task instanceof RemapJarTask && ((RemapJarTask) task).getAddNestedDependencies().getOrElse(false)) { //Run all the sub project remap jars tasks before the root projects jar, this is to allow us to include projects @@ -384,6 +404,7 @@ public class AbstractPlugin implements Plugin { // add modsCompile to maven-publish PublishingExtension mavenPublish = p.getExtensions().findByType(PublishingExtension.class); + if (mavenPublish != null) { mavenPublish.publications((publications) -> { for (Publication publication : publications) { @@ -393,15 +414,14 @@ public class AbstractPlugin implements Plugin { Node dependencies = GroovyXmlUtil.getOrCreateNode(xml.asNode(), "dependencies"); Set foundArtifacts = new HashSet<>(); - GroovyXmlUtil.childrenNodesStream(dependencies) - .filter((n) -> "dependency".equals(n.name())) - .forEach((n) -> { - Optional groupId = GroovyXmlUtil.getNode(n, "groupId"); - Optional artifactId = GroovyXmlUtil.getNode(n, "artifactId"); - if (groupId.isPresent() && artifactId.isPresent()) { - foundArtifacts.add(groupId.get().text() + ":" + artifactId.get().text()); - } - }); + GroovyXmlUtil.childrenNodesStream(dependencies).filter((n) -> "dependency".equals(n.name())).forEach((n) -> { + Optional groupId = GroovyXmlUtil.getNode(n, "groupId"); + Optional artifactId = GroovyXmlUtil.getNode(n, "artifactId"); + + if (groupId.isPresent() && artifactId.isPresent()) { + foundArtifacts.add(groupId.get().text() + ":" + artifactId.get().text()); + } + }); for (Dependency dependency : compileModsConfig.getAllDependencies()) { if (foundArtifacts.contains(dependency.getGroup() + ":" + dependency.getName())) { diff --git a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java index eefd48f..2b590b8 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java +++ b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java @@ -24,28 +24,30 @@ package net.fabricmc.loom; +import java.io.File; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.function.BiPredicate; +import java.util.function.Function; +import java.util.function.Supplier; + +import javax.annotation.Nullable; + import com.google.gson.JsonObject; +import org.cadixdev.lorenz.MappingSet; +import org.cadixdev.mercury.Mercury; +import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.artifacts.Dependency; + import net.fabricmc.loom.providers.MappingsProvider; import net.fabricmc.loom.providers.MinecraftMappedProvider; import net.fabricmc.loom.providers.MinecraftProvider; import net.fabricmc.loom.util.LoomDependencyManager; -import org.cadixdev.lorenz.MappingSet; -import org.cadixdev.mercury.Mercury; -import org.gradle.api.Project; -import org.gradle.api.UnknownDomainObjectException; -import org.gradle.api.artifacts.Configuration; -import org.gradle.api.artifacts.Dependency; -import org.gradle.api.artifacts.component.ComponentIdentifier; -import org.gradle.api.artifacts.component.ModuleComponentIdentifier; -import org.gradle.api.artifacts.result.ResolvedArtifactResult; - -import javax.annotation.Nullable; -import java.io.File; -import java.nio.file.Path; -import java.util.*; -import java.util.function.BiPredicate; -import java.util.function.Function; -import java.util.function.Supplier; public class LoomGradleExtension { public String runDir = "run"; @@ -87,77 +89,93 @@ public class LoomGradleExtension { } public void setInstallerJson(JsonObject object, int priority) { - if (installerJson == null || priority <= installerJsonPriority) { - this.installerJson = object; - this.installerJsonPriority = priority; - } - } + if (installerJson == null || priority <= installerJsonPriority) { + this.installerJson = object; + this.installerJsonPriority = priority; + } + } - public JsonObject getInstallerJson() { - return installerJson; - } + public JsonObject getInstallerJson() { + return installerJson; + } public File getUserCache() { File userCache = new File(project.getGradle().getGradleUserHomeDir(), "caches" + File.separator + "fabric-loom"); + if (!userCache.exists()) { userCache.mkdirs(); } + return userCache; } public File getRootProjectPersistentCache() { File projectCache = new File(project.getRootProject().file(".gradle"), "loom-cache"); - if(!projectCache.exists()){ + + if (!projectCache.exists()) { projectCache.mkdirs(); } + return projectCache; } public File getRootProjectBuildCache() { File projectCache = new File(project.getRootProject().getBuildDir(), "loom-cache"); - if(!projectCache.exists()){ + + if (!projectCache.exists()) { projectCache.mkdirs(); } + return projectCache; } public File getProjectBuildCache() { File projectCache = new File(project.getBuildDir(), "loom-cache"); - if(!projectCache.exists()){ + + if (!projectCache.exists()) { projectCache.mkdirs(); } + return projectCache; } public File getRemappedModCache() { File remappedModCache = new File(getRootProjectPersistentCache(), "remapped_mods"); + if (!remappedModCache.exists()) { remappedModCache.mkdir(); } + return remappedModCache; } public File getNestedModCache() { File nestedModCache = new File(getRootProjectPersistentCache(), "nested_mods"); + if (!nestedModCache.exists()) { nestedModCache.mkdir(); } + return nestedModCache; } - public File getNativesJarStore(){ + public File getNativesJarStore() { File natives = new File(getUserCache(), "natives/jars"); - if(!natives.exists()) { + + if (!natives.exists()) { natives.mkdirs(); } + return natives; } - public File getNativesDirectory(){ + public File getNativesDirectory() { File natives = new File(getUserCache(), "natives/" + getMinecraftProvider().minecraftVersion); - if(!natives.exists()) { + + if (!natives.exists()) { natives.mkdirs(); } + return natives; } @@ -167,6 +185,7 @@ public class LoomGradleExtension { for (Dependency dependency : config.getDependencies()) { String group = dependency.getGroup(); String name = dependency.getName(); + if (groupNameFilter.test(group, name)) { p.getLogger().debug("Loom findDependency found: " + group + ":" + name + ":" + dependency.getVersion()); return dependency; @@ -181,12 +200,15 @@ public class LoomGradleExtension { private T recurseProjects(Function projectTFunction) { Project p = this.project; T result; + while (!AbstractPlugin.isRootProject(p)) { if ((result = projectTFunction.apply(p)) != null) { return result; } + p = p.getRootProject(); } + result = projectTFunction.apply(p); return result; } @@ -197,9 +219,11 @@ public class LoomGradleExtension { List configs = new ArrayList<>(); // check compile classpath first Configuration possibleCompileClasspath = p.getConfigurations().findByName("compileClasspath"); + if (possibleCompileClasspath != null) { configs.add(possibleCompileClasspath); } + // failing that, buildscript configs.addAll(p.getBuildscript().getConfigurations()); @@ -242,15 +266,15 @@ public class LoomGradleExtension { return dependencyManager; } - public MinecraftProvider getMinecraftProvider(){ + public MinecraftProvider getMinecraftProvider() { return getDependencyManager().getProvider(MinecraftProvider.class); } - public MinecraftMappedProvider getMinecraftMappedProvider(){ + public MinecraftMappedProvider getMinecraftMappedProvider() { return getMappingsProvider().mappedProvider; } - public MappingsProvider getMappingsProvider(){ + public MappingsProvider getMappingsProvider() { return getDependencyManager().getProvider(MappingsProvider.class); } @@ -259,7 +283,7 @@ public class LoomGradleExtension { } public String getRefmapName() { - if(refmapName == null || refmapName.isEmpty()){ + if (refmapName == null || refmapName.isEmpty()) { project.getLogger().warn("Could not find refmap definition, will be using default name: " + project.getName() + "-refmap.json"); refmapName = project.getName() + "-refmap.json"; } diff --git a/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java b/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java index 423827f..624fabd 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java +++ b/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java @@ -24,26 +24,40 @@ package net.fabricmc.loom; -import net.fabricmc.loom.providers.MappingsProvider; -import net.fabricmc.loom.providers.MinecraftLibraryProvider; -import net.fabricmc.loom.task.*; -import net.fabricmc.loom.task.fernflower.FernFlowerTask; -import org.gradle.api.Project; -import org.gradle.api.Task; -import org.gradle.api.tasks.TaskContainer; - import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Locale; +import org.gradle.api.Project; +import org.gradle.api.Task; +import org.gradle.api.tasks.TaskContainer; + +import net.fabricmc.loom.providers.MappingsProvider; +import net.fabricmc.loom.providers.MinecraftLibraryProvider; +import net.fabricmc.loom.task.AbstractDecompileTask; +import net.fabricmc.loom.task.CleanLoomBinaries; +import net.fabricmc.loom.task.CleanLoomMappings; +import net.fabricmc.loom.task.DownloadAssetsTask; +import net.fabricmc.loom.task.GenEclipseRunsTask; +import net.fabricmc.loom.task.GenIdeaProjectTask; +import net.fabricmc.loom.task.GenVsCodeProjectTask; +import net.fabricmc.loom.task.MigrateMappingsTask; +import net.fabricmc.loom.task.RemapJarTask; +import net.fabricmc.loom.task.RemapLineNumbersTask; +import net.fabricmc.loom.task.RemapSourcesJarTask; +import net.fabricmc.loom.task.RunClientTask; +import net.fabricmc.loom.task.RunServerTask; +import net.fabricmc.loom.task.fernflower.FernFlowerTask; + public class LoomGradlePlugin extends AbstractPlugin { private static File getMappedByproduct(Project project, String suffix) { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); MappingsProvider mappingsProvider = extension.getMappingsProvider(); File mappedJar = mappingsProvider.mappedProvider.getMappedJar(); String path = mappedJar.getAbsolutePath(); + if (!path.toLowerCase(Locale.ROOT).endsWith(".jar")) { throw new RuntimeException("Invalid mapped JAR path: " + path); } @@ -57,7 +71,6 @@ public class LoomGradlePlugin extends AbstractPlugin { TaskContainer tasks = target.getTasks(); - tasks.register("cleanLoomBinaries", CleanLoomBinaries.class); tasks.register("cleanLoomMappings", CleanLoomMappings.class); diff --git a/src/main/java/net/fabricmc/loom/providers/MappingsCache.java b/src/main/java/net/fabricmc/loom/providers/MappingsCache.java index fd6018e..953f694 100644 --- a/src/main/java/net/fabricmc/loom/providers/MappingsCache.java +++ b/src/main/java/net/fabricmc/loom/providers/MappingsCache.java @@ -24,41 +24,42 @@ package net.fabricmc.loom.providers; -import net.fabricmc.loom.util.StaticPathWatcher; -import net.fabricmc.mappings.Mappings; -import org.gradle.api.logging.Logging; - -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.ref.SoftReference; -import java.nio.file.*; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.HashMap; import java.util.Map; +import net.fabricmc.loom.util.StaticPathWatcher; +import net.fabricmc.mappings.Mappings; + public final class MappingsCache { - public static final MappingsCache INSTANCE = new MappingsCache(); + public static final MappingsCache INSTANCE = new MappingsCache(); - private final Map> mappingsCache = new HashMap<>(); + private final Map> mappingsCache = new HashMap<>(); - public Mappings get(Path mappingsPath) { - mappingsPath = mappingsPath.toAbsolutePath(); - if (StaticPathWatcher.INSTANCE.hasFileChanged(mappingsPath)) { - mappingsCache.remove(mappingsPath); - } + public Mappings get(Path mappingsPath) { + mappingsPath = mappingsPath.toAbsolutePath(); - SoftReference 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); - ref = new SoftReference<>(mappings); - mappingsCache.put(mappingsPath, ref); - return mappings; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } + if (StaticPathWatcher.INSTANCE.hasFileChanged(mappingsPath)) { + mappingsCache.remove(mappingsPath); + } + + SoftReference 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); + ref = new SoftReference<>(mappings); + mappingsCache.put(mappingsPath, ref); + return mappings; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } } diff --git a/src/main/java/net/fabricmc/loom/providers/MappingsProvider.java b/src/main/java/net/fabricmc/loom/providers/MappingsProvider.java index 35ee05e..3eddfc5 100644 --- a/src/main/java/net/fabricmc/loom/providers/MappingsProvider.java +++ b/src/main/java/net/fabricmc/loom/providers/MappingsProvider.java @@ -24,23 +24,22 @@ package net.fabricmc.loom.providers; +import java.io.File; +import java.io.IOException; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.function.Consumer; + +import org.gradle.api.Project; + import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.DependencyProvider; import net.fabricmc.loom.util.Version; import net.fabricmc.mappings.Mappings; import net.fabricmc.stitch.commands.CommandProposeFieldNames; -import org.gradle.api.Project; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.lang.ref.SoftReference; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.function.Consumer; //TODO fix local mappings //TODO possibly use maven for mappings, can fix above at the same time @@ -84,6 +83,7 @@ public class MappingsProvider extends DependencyProvider { if (!MAPPINGS_TINY_BASE.exists() || !MAPPINGS_TINY.exists()) { if (!MAPPINGS_TINY_BASE.exists()) { project.getLogger().lifecycle(":extracting " + mappingsJar.getName()); + try (FileSystem fileSystem = FileSystems.newFileSystem(mappingsJar.toPath(), null)) { Path fileToExtract = fileSystem.getPath("mappings/mappings.tiny"); Files.copy(fileToExtract, MAPPINGS_TINY_BASE.toPath()); @@ -95,11 +95,7 @@ public class MappingsProvider extends DependencyProvider { } project.getLogger().lifecycle(":populating field names"); - new CommandProposeFieldNames().run(new String[] { - minecraftProvider.MINECRAFT_MERGED_JAR.getAbsolutePath(), - MAPPINGS_TINY_BASE.getAbsolutePath(), - MAPPINGS_TINY.getAbsolutePath() - }); + new CommandProposeFieldNames().run(new String[]{minecraftProvider.MINECRAFT_MERGED_JAR.getAbsolutePath(), MAPPINGS_TINY_BASE.getAbsolutePath(), MAPPINGS_TINY.getAbsolutePath()}); } mappedProvider = new MinecraftMappedProvider(); diff --git a/src/main/java/net/fabricmc/loom/providers/MinecraftAssetsProvider.java b/src/main/java/net/fabricmc/loom/providers/MinecraftAssetsProvider.java index 738c11b..ed5bdaa 100644 --- a/src/main/java/net/fabricmc/loom/providers/MinecraftAssetsProvider.java +++ b/src/main/java/net/fabricmc/loom/providers/MinecraftAssetsProvider.java @@ -24,7 +24,16 @@ package net.fabricmc.loom.providers; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.net.URL; +import java.util.Map; + import com.google.gson.Gson; +import org.gradle.api.GradleException; +import org.gradle.api.Project; + import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.util.Checksum; import net.fabricmc.loom.util.Constants; @@ -34,15 +43,6 @@ import net.fabricmc.loom.util.assets.AssetIndex; import net.fabricmc.loom.util.assets.AssetObject; import net.fabricmc.loom.util.progress.ProgressLogger; -import org.gradle.api.GradleException; -import org.gradle.api.Project; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.net.URL; -import java.util.Map; - public class MinecraftAssetsProvider { public static void provide(MinecraftProvider minecraftProvider, Project project) throws IOException { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); @@ -53,13 +53,16 @@ public class MinecraftAssetsProvider { // get existing cache files File assets = new File(extension.getUserCache(), "assets"); + if (!assets.exists()) { assets.mkdirs(); } File assetsInfo = new File(assets, "indexes" + File.separator + assetIndex.getFabricId(minecraftProvider.minecraftVersion) + ".json"); + if (!assetsInfo.exists() || !Checksum.equals(assetsInfo, assetIndex.sha1)) { project.getLogger().lifecycle(":downloading asset index"); + if (offline) { if (assetsInfo.exists()) { //We know it's outdated but can't do anything about it, oh well @@ -76,13 +79,16 @@ public class MinecraftAssetsProvider { ProgressLogger progressLogger = ProgressLogger.getProgressFactory(project, MinecraftAssetsProvider.class.getName()); progressLogger.start("Downloading assets...", "assets"); AssetIndex index; + try (FileReader fileReader = new FileReader(assetsInfo)) { index = new Gson().fromJson(fileReader, AssetIndex.class); } + Map parent = index.getFileMap(); final int totalSize = parent.size(); int position = 0; project.getLogger().lifecycle(":downloading assets..."); + for (Map.Entry entry : parent.entrySet()) { AssetObject object = entry.getValue(); String sha1 = object.getHash(); @@ -101,11 +107,14 @@ public class MinecraftAssetsProvider { DownloadUtil.downloadIfChanged(new URL(Constants.RESOURCES_BASE + sha1.substring(0, 2) + "/" + sha1), file, project.getLogger(), true); } } + String assetName = entry.getKey(); int end = assetName.lastIndexOf("/") + 1; + if (end > 0) { assetName = assetName.substring(end); } + progressLogger.progress(assetName + " - " + position + "/" + totalSize + " (" + (int) ((position / (double) totalSize) * 100) + "%) assets downloaded"); position++; } diff --git a/src/main/java/net/fabricmc/loom/providers/MinecraftLibraryProvider.java b/src/main/java/net/fabricmc/loom/providers/MinecraftLibraryProvider.java index f218ddc..5958319 100644 --- a/src/main/java/net/fabricmc/loom/providers/MinecraftLibraryProvider.java +++ b/src/main/java/net/fabricmc/loom/providers/MinecraftLibraryProvider.java @@ -24,27 +24,18 @@ package net.fabricmc.loom.providers; -import com.google.gson.Gson; -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.util.Checksum; -import net.fabricmc.loom.util.Constants; -import net.fabricmc.loom.util.DownloadUtil; -import net.fabricmc.loom.util.MinecraftVersionInfo; -import net.fabricmc.loom.util.assets.AssetIndex; -import net.fabricmc.loom.util.assets.AssetObject; -import net.fabricmc.loom.util.progress.ProgressLogger; -import org.gradle.api.Project; - import java.io.File; -import java.io.FileReader; import java.io.IOException; -import java.net.URL; import java.util.Collection; import java.util.HashSet; -import java.util.Map; + +import org.gradle.api.Project; + +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.util.Constants; +import net.fabricmc.loom.util.MinecraftVersionInfo; public class MinecraftLibraryProvider { - public File MINECRAFT_LIBS; private Collection libs = new HashSet<>(); @@ -61,6 +52,7 @@ public class MinecraftLibraryProvider { // By default, they are all available on all sides /* boolean isClientOnly = false; + if (library.name.contains("java3d") || library.name.contains("paulscode") || library.name.contains("lwjgl") || library.name.contains("twitch") || library.name.contains("jinput") || library.name.contains("text2speech") || library.name.contains("objc")) { isClientOnly = true; } */ @@ -78,5 +70,4 @@ public class MinecraftLibraryProvider { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); MINECRAFT_LIBS = new File(extension.getUserCache(), "libraries"); } - } diff --git a/src/main/java/net/fabricmc/loom/providers/MinecraftMappedProvider.java b/src/main/java/net/fabricmc/loom/providers/MinecraftMappedProvider.java index 0ad1069..9d44c0d 100644 --- a/src/main/java/net/fabricmc/loom/providers/MinecraftMappedProvider.java +++ b/src/main/java/net/fabricmc/loom/providers/MinecraftMappedProvider.java @@ -24,73 +24,76 @@ package net.fabricmc.loom.providers; -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.util.Constants; -import net.fabricmc.loom.util.DependencyProvider; -import net.fabricmc.loom.util.MapJarsTiny; -import org.gradle.api.Project; - import java.io.File; import java.util.Collection; import java.util.function.Consumer; +import org.gradle.api.Project; + +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.util.Constants; +import net.fabricmc.loom.util.DependencyProvider; +import net.fabricmc.loom.util.MapJarsTiny; + public class MinecraftMappedProvider extends DependencyProvider { - public File MINECRAFT_MAPPED_JAR; - public File MINECRAFT_INTERMEDIARY_JAR; + public File MINECRAFT_MAPPED_JAR; + public File MINECRAFT_INTERMEDIARY_JAR; - private MinecraftProvider minecraftProvider; + private MinecraftProvider minecraftProvider; - @Override - public void provide(DependencyInfo dependency, Project project, LoomGradleExtension extension, Consumer postPopulationScheduler) throws Exception { - if (!extension.getMappingsProvider().MAPPINGS_TINY.exists()) { - throw new RuntimeException("mappings file not found"); - } + @Override + public void provide(DependencyInfo dependency, Project project, LoomGradleExtension extension, Consumer postPopulationScheduler) throws Exception { + if (!extension.getMappingsProvider().MAPPINGS_TINY.exists()) { + throw new RuntimeException("mappings file not found"); + } - if (!extension.getMinecraftProvider().getMergedJar().exists()) { - throw new RuntimeException("input merged jar not found"); - } + if (!extension.getMinecraftProvider().getMergedJar().exists()) { + throw new RuntimeException("input merged jar not found"); + } - if(!getMappedJar().exists() || !getIntermediaryJar().exists()){ - if (getMappedJar().exists()) { - getMappedJar().delete(); - } - if (getIntermediaryJar().exists()) { - getIntermediaryJar().delete(); - } - new MapJarsTiny().mapJars(minecraftProvider, this, project); - } + if (!getMappedJar().exists() || !getIntermediaryJar().exists()) { + if (getMappedJar().exists()) { + getMappedJar().delete(); + } - if (!MINECRAFT_MAPPED_JAR.exists()) { - throw new RuntimeException("mapped jar not found"); - } + if (getIntermediaryJar().exists()) { + getIntermediaryJar().delete(); + } - 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)); - } + new MapJarsTiny().mapJars(minecraftProvider, this, project); + } - 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"); - } + if (!MINECRAFT_MAPPED_JAR.exists()) { + throw new RuntimeException("mapped jar not found"); + } - public Collection getMapperPaths() { - return minecraftProvider.libraryProvider.getLibraries(); - } + 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)); + } - public File getIntermediaryJar() { - return MINECRAFT_INTERMEDIARY_JAR; - } + 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"); + } - public File getMappedJar() { - return MINECRAFT_MAPPED_JAR; - } + public Collection getMapperPaths() { + return minecraftProvider.libraryProvider.getLibraries(); + } - @Override - public String getTargetConfig() { - return Constants.MINECRAFT_NAMED; - } + public File getIntermediaryJar() { + return MINECRAFT_INTERMEDIARY_JAR; + } + + public File getMappedJar() { + return MINECRAFT_MAPPED_JAR; + } + + @Override + public String getTargetConfig() { + return Constants.MINECRAFT_NAMED; + } } diff --git a/src/main/java/net/fabricmc/loom/providers/MinecraftNativesProvider.java b/src/main/java/net/fabricmc/loom/providers/MinecraftNativesProvider.java index c4c91fd..34f3a0b 100644 --- a/src/main/java/net/fabricmc/loom/providers/MinecraftNativesProvider.java +++ b/src/main/java/net/fabricmc/loom/providers/MinecraftNativesProvider.java @@ -24,18 +24,18 @@ package net.fabricmc.loom.providers; -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.util.DownloadUtil; -import net.fabricmc.loom.util.MinecraftVersionInfo; -import org.gradle.api.Project; -import org.zeroturnaround.zip.ZipUtil; - import java.io.File; import java.io.IOException; import java.net.URL; -public class MinecraftNativesProvider { +import org.zeroturnaround.zip.ZipUtil; +import org.gradle.api.Project; +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.util.DownloadUtil; +import net.fabricmc.loom.util.MinecraftVersionInfo; + +public class MinecraftNativesProvider { public static void provide(MinecraftProvider minecraftProvider, Project project) throws IOException { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); MinecraftVersionInfo versionInfo = minecraftProvider.versionInfo; @@ -45,6 +45,7 @@ public class MinecraftNativesProvider { for (MinecraftVersionInfo.Library library : versionInfo.libraries) { File libJarFile = library.getFile(jarStore); + if (library.allowed() && library.isNative() && libJarFile != null) { DownloadUtil.downloadIfChanged(new URL(library.getURL()), libJarFile, project.getLogger()); @@ -53,5 +54,4 @@ public class MinecraftNativesProvider { } } } - } diff --git a/src/main/java/net/fabricmc/loom/providers/MinecraftProvider.java b/src/main/java/net/fabricmc/loom/providers/MinecraftProvider.java index f88074a..c8ff87d 100644 --- a/src/main/java/net/fabricmc/loom/providers/MinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/providers/MinecraftProvider.java @@ -24,17 +24,6 @@ package net.fabricmc.loom.providers; -import com.google.common.io.Files; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.util.*; -import net.fabricmc.stitch.merge.JarMerger; - -import org.gradle.api.GradleException; -import org.gradle.api.Project; -import org.gradle.api.logging.Logger; - import java.io.File; import java.io.FileReader; import java.io.IOException; @@ -44,8 +33,24 @@ import java.util.Optional; import java.util.function.Consumer; import java.util.zip.ZipError; -public class MinecraftProvider extends DependencyProvider { +import com.google.common.io.Files; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import org.gradle.api.GradleException; +import org.gradle.api.Project; +import org.gradle.api.logging.Logger; +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.util.Checksum; +import net.fabricmc.loom.util.Constants; +import net.fabricmc.loom.util.DependencyProvider; +import net.fabricmc.loom.util.DownloadUtil; +import net.fabricmc.loom.util.ManifestVersion; +import net.fabricmc.loom.util.MinecraftVersionInfo; +import net.fabricmc.loom.util.StaticPathWatcher; +import net.fabricmc.stitch.merge.JarMerger; + +public class MinecraftProvider extends DependencyProvider { public String minecraftVersion; public MinecraftVersionInfo versionInfo; @@ -66,25 +71,26 @@ public class MinecraftProvider extends DependencyProvider { initFiles(project); downloadMcJson(project, offline); + try (FileReader reader = new FileReader(MINECRAFT_JSON)) { versionInfo = gson.fromJson(reader, MinecraftVersionInfo.class); } // Add Loom as an annotation processor - addDependency(project.files(this.getClass().getProtectionDomain().getCodeSource().getLocation()), project, "compileOnly"); + addDependency(project.files(this.getClass().getProtectionDomain().getCodeSource().getLocation()), project, "compileOnly"); - if (offline) { - if (MINECRAFT_CLIENT_JAR.exists() && MINECRAFT_SERVER_JAR.exists()) { - project.getLogger().debug("Found client and server jars, presuming up-to-date"); - } else if (MINECRAFT_MERGED_JAR.exists()) { - //Strictly we don't need the split jars if the merged one exists, let's try go on - project.getLogger().warn("Missing game jar but merged jar present, things might end badly"); - } else { - throw new GradleException("Missing jar(s); Client: " + MINECRAFT_CLIENT_JAR.exists() + ", Server: " + MINECRAFT_SERVER_JAR.exists()); - } - } else { - downloadJars(project.getLogger()); - } + if (offline) { + if (MINECRAFT_CLIENT_JAR.exists() && MINECRAFT_SERVER_JAR.exists()) { + project.getLogger().debug("Found client and server jars, presuming up-to-date"); + } else if (MINECRAFT_MERGED_JAR.exists()) { + //Strictly we don't need the split jars if the merged one exists, let's try go on + project.getLogger().warn("Missing game jar but merged jar present, things might end badly"); + } else { + throw new GradleException("Missing jar(s); Client: " + MINECRAFT_CLIENT_JAR.exists() + ", Server: " + MINECRAFT_SERVER_JAR.exists()); + } + } else { + downloadJars(project.getLogger()); + } libraryProvider = new MinecraftLibraryProvider(); libraryProvider.provide(this, project); @@ -108,7 +114,6 @@ public class MinecraftProvider extends DependencyProvider { MINECRAFT_CLIENT_JAR = new File(extension.getUserCache(), "minecraft-" + minecraftVersion + "-client.jar"); MINECRAFT_SERVER_JAR = new File(extension.getUserCache(), "minecraft-" + minecraftVersion + "-server.jar"); MINECRAFT_MERGED_JAR = new File(extension.getUserCache(), "minecraft-" + minecraftVersion + "-merged.jar"); - } private void downloadMcJson(Project project, boolean offline) throws IOException { @@ -135,7 +140,7 @@ public class MinecraftProvider extends DependencyProvider { Optional optionalVersion = Optional.empty(); - if(extension.customManifest != null){ + if (extension.customManifest != null) { ManifestVersion.Versions customVersion = new ManifestVersion.Versions(); customVersion.id = minecraftVersion; customVersion.url = extension.customManifest; @@ -143,7 +148,7 @@ public class MinecraftProvider extends DependencyProvider { project.getLogger().lifecycle("Using custom minecraft manifest"); } - if(!optionalVersion.isPresent()){ + if (!optionalVersion.isPresent()) { optionalVersion = mcManifest.versions.stream().filter(versions -> versions.id.equalsIgnoreCase(minecraftVersion)).findFirst(); } @@ -165,7 +170,6 @@ public class MinecraftProvider extends DependencyProvider { } else { throw new RuntimeException("Failed to find minecraft version: " + minecraftVersion); } - } private void downloadJars(Logger logger) throws IOException { @@ -182,6 +186,7 @@ public class MinecraftProvider extends DependencyProvider { private void mergeJars(Logger logger) throws IOException { logger.lifecycle(":merging jars"); + try (JarMerger jarMerger = new JarMerger(MINECRAFT_CLIENT_JAR, MINECRAFT_SERVER_JAR, MINECRAFT_MERGED_JAR)) { jarMerger.enableSyntheticParamsOffset(); jarMerger.merge(); diff --git a/src/main/java/net/fabricmc/loom/task/AbstractDecompileTask.java b/src/main/java/net/fabricmc/loom/task/AbstractDecompileTask.java index 14deb34..c7403a9 100644 --- a/src/main/java/net/fabricmc/loom/task/AbstractDecompileTask.java +++ b/src/main/java/net/fabricmc/loom/task/AbstractDecompileTask.java @@ -24,29 +24,52 @@ package net.fabricmc.loom.task; +import java.io.File; + import org.gradle.api.file.FileCollection; -import org.gradle.api.tasks.Input; import org.gradle.api.tasks.InputFile; import org.gradle.api.tasks.InputFiles; import org.gradle.api.tasks.OutputFile; -import java.io.File; - public abstract class AbstractDecompileTask extends AbstractLoomTask { - private Object input; - private Object output; - private Object lineMapFile; - private Object libraries; + private Object input; + private Object output; + private Object lineMapFile; + private Object libraries; - //@formatter:off - @InputFile - public File getInput() { return getProject().file(input); } - @OutputFile public File getOutput() { return getProject().file(output); } - @OutputFile public File getLineMapFile() { return getProject().file(lineMapFile); } - @InputFiles public FileCollection getLibraries() { return getProject().files(libraries); } - public void setInput(Object input) { this.input = input; } - public void setOutput(Object output) { this.output = output; } - public void setLineMapFile(Object lineMapFile) { this.lineMapFile = lineMapFile; } - public void setLibraries(Object libraries) { this.libraries = libraries; } - //@formatter:on + @InputFile + public File getInput() { + return getProject().file(input); + } + + @OutputFile + public File getOutput() { + return getProject().file(output); + } + + @OutputFile + public File getLineMapFile() { + return getProject().file(lineMapFile); + } + + @InputFiles + public FileCollection getLibraries() { + return getProject().files(libraries); + } + + public void setInput(Object input) { + this.input = input; + } + + public void setOutput(Object output) { + this.output = output; + } + + public void setLineMapFile(Object lineMapFile) { + this.lineMapFile = lineMapFile; + } + + public void setLibraries(Object libraries) { + this.libraries = libraries; + } } diff --git a/src/main/java/net/fabricmc/loom/task/AbstractLoomTask.java b/src/main/java/net/fabricmc/loom/task/AbstractLoomTask.java index cd39ecf..d062e4d 100644 --- a/src/main/java/net/fabricmc/loom/task/AbstractLoomTask.java +++ b/src/main/java/net/fabricmc/loom/task/AbstractLoomTask.java @@ -27,9 +27,7 @@ package net.fabricmc.loom.task; import org.gradle.api.DefaultTask; public abstract class AbstractLoomTask extends DefaultTask { - public AbstractLoomTask() { setGroup("fabric"); } - } diff --git a/src/main/java/net/fabricmc/loom/task/AbstractRunTask.java b/src/main/java/net/fabricmc/loom/task/AbstractRunTask.java index 0780c81..d48d4a5 100644 --- a/src/main/java/net/fabricmc/loom/task/AbstractRunTask.java +++ b/src/main/java/net/fabricmc/loom/task/AbstractRunTask.java @@ -24,14 +24,6 @@ package net.fabricmc.loom.task; -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.providers.MappingsProvider; -import net.fabricmc.loom.util.MinecraftVersionInfo; -import net.fabricmc.loom.util.OperatingSystem; -import net.fabricmc.loom.util.RunConfig; -import org.gradle.api.Project; -import org.gradle.api.tasks.JavaExec; - import java.io.File; import java.nio.file.Files; import java.nio.file.Path; @@ -41,99 +33,113 @@ import java.util.Collections; import java.util.List; import java.util.function.Function; +import org.gradle.api.Project; +import org.gradle.api.tasks.JavaExec; + +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.providers.MappingsProvider; +import net.fabricmc.loom.util.MinecraftVersionInfo; +import net.fabricmc.loom.util.RunConfig; + public abstract class AbstractRunTask extends JavaExec { - private final Function configProvider; - private RunConfig config; + private final Function configProvider; + private RunConfig config; - public AbstractRunTask(Function config) { - super(); - setGroup("fabric"); - this.configProvider = config; - } + public AbstractRunTask(Function config) { + super(); + setGroup("fabric"); + this.configProvider = config; + } - @Override - public void exec() { - if (config == null) { - config = configProvider.apply(getProject()); - } + @Override + public void exec() { + if (config == null) { + config = configProvider.apply(getProject()); + } - LoomGradleExtension extension = this.getProject().getExtensions().getByType(LoomGradleExtension.class); - MinecraftVersionInfo minecraftVersionInfo = extension.getMinecraftProvider().versionInfo; - MappingsProvider mappingsProvider = extension.getMappingsProvider(); + LoomGradleExtension extension = this.getProject().getExtensions().getByType(LoomGradleExtension.class); + MinecraftVersionInfo minecraftVersionInfo = extension.getMinecraftProvider().versionInfo; + MappingsProvider mappingsProvider = extension.getMappingsProvider(); - List libs = new ArrayList<>(); - for (File file : getProject().getConfigurations().getByName("runtimeClasspath").getFiles()) { - libs.add(file.getAbsolutePath()); - } - for (Path file : extension.getUnmappedMods()) { - if (Files.isRegularFile(file)) { - libs.add(file.toFile().getAbsolutePath()); - } - } + List libs = new ArrayList<>(); - classpath(libs); - List argsSplit = new ArrayList<>(); - String[] args = config.programArgs.split(" "); - int partPos = -1; - for (int i = 0; i < args.length; i++) { - if (partPos < 0) { - if (args[i].startsWith("\"")) { - if (args[i].endsWith("\"")) { - argsSplit.add(args[i].substring(1, args[i].length() - 1)); - } else { - partPos = i; - } - } else { - argsSplit.add(args[i]); - } - } else if (args[i].endsWith("\"")) { - StringBuilder builder = new StringBuilder(args[partPos].substring(1)); - for (int j = partPos + 1; j < i; j++) { - builder.append(" ").append(args[j]); - } - builder.append(" ").append(args[i], 0, args[i].length() - 1); - argsSplit.add(builder.toString()); - partPos = -1; - } - } + for (File file : getProject().getConfigurations().getByName("runtimeClasspath").getFiles()) { + libs.add(file.getAbsolutePath()); + } - args(argsSplit); - setWorkingDir(new File(getProject().getRootDir(), extension.runDir)); + for (Path file : extension.getUnmappedMods()) { + if (Files.isRegularFile(file)) { + libs.add(file.toFile().getAbsolutePath()); + } + } - super.exec(); - } + classpath(libs); + List argsSplit = new ArrayList<>(); + String[] args = config.programArgs.split(" "); + int partPos = -1; - @Override - public void setWorkingDir(File dir) { - if (config == null) { - config = configProvider.apply(getProject()); - } + for (int i = 0; i < args.length; i++) { + if (partPos < 0) { + if (args[i].startsWith("\"")) { + if (args[i].endsWith("\"")) { + argsSplit.add(args[i].substring(1, args[i].length() - 1)); + } else { + partPos = i; + } + } else { + argsSplit.add(args[i]); + } + } else if (args[i].endsWith("\"")) { + StringBuilder builder = new StringBuilder(args[partPos].substring(1)); - if(!dir.exists()){ - dir.mkdirs(); - } - super.setWorkingDir(dir); - } + for (int j = partPos + 1; j < i; j++) { + builder.append(" ").append(args[j]); + } - @Override - public String getMain() { - if (config == null) { - config = configProvider.apply(getProject()); - } + builder.append(" ").append(args[i], 0, args[i].length() - 1); + argsSplit.add(builder.toString()); + partPos = -1; + } + } - return config.mainClass; - } + args(argsSplit); + setWorkingDir(new File(getProject().getRootDir(), extension.runDir)); - @Override - public List getJvmArgs() { - if (config == null) { - config = configProvider.apply(getProject()); - } - - LoomGradleExtension extension = this.getProject().getExtensions().getByType(LoomGradleExtension.class); - List superArgs = super.getJvmArgs(); - List args = new ArrayList<>(superArgs != null ? superArgs : Collections.emptyList()); - args.addAll(Arrays.asList(config.vmArgs.split(" "))); - return args; - } + super.exec(); + } + + @Override + public void setWorkingDir(File dir) { + if (config == null) { + config = configProvider.apply(getProject()); + } + + if (!dir.exists()) { + dir.mkdirs(); + } + + super.setWorkingDir(dir); + } + + @Override + public String getMain() { + if (config == null) { + config = configProvider.apply(getProject()); + } + + return config.mainClass; + } + + @Override + public List getJvmArgs() { + if (config == null) { + config = configProvider.apply(getProject()); + } + + LoomGradleExtension extension = this.getProject().getExtensions().getByType(LoomGradleExtension.class); + List superArgs = super.getJvmArgs(); + List args = new ArrayList<>(superArgs != null ? superArgs : Collections.emptyList()); + args.addAll(Arrays.asList(config.vmArgs.split(" "))); + return args; + } } diff --git a/src/main/java/net/fabricmc/loom/task/CleanLoomBinaries.java b/src/main/java/net/fabricmc/loom/task/CleanLoomBinaries.java index 9c7f61d..ebe13ab 100644 --- a/src/main/java/net/fabricmc/loom/task/CleanLoomBinaries.java +++ b/src/main/java/net/fabricmc/loom/task/CleanLoomBinaries.java @@ -24,26 +24,28 @@ package net.fabricmc.loom.task; -import net.fabricmc.loom.LoomGradleExtension; +import java.io.IOException; + import org.apache.commons.io.FileUtils; import org.gradle.api.Project; import org.gradle.api.tasks.TaskAction; -import java.io.IOException; +import net.fabricmc.loom.LoomGradleExtension; public class CleanLoomBinaries extends AbstractLoomTask { - @TaskAction - public void run() { - Project project = this.getProject(); - LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); - extension.getMinecraftProvider().getMergedJar().delete(); - extension.getMinecraftMappedProvider().getIntermediaryJar().delete(); - extension.getMinecraftMappedProvider().getMappedJar().delete(); - try { - FileUtils.deleteDirectory(extension.getNativesDirectory()); - FileUtils.deleteDirectory(extension.getNativesJarStore()); - } catch (IOException e) { - e.printStackTrace(); - } - } + @TaskAction + public void run() { + Project project = this.getProject(); + LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); + extension.getMinecraftProvider().getMergedJar().delete(); + extension.getMinecraftMappedProvider().getIntermediaryJar().delete(); + extension.getMinecraftMappedProvider().getMappedJar().delete(); + + try { + FileUtils.deleteDirectory(extension.getNativesDirectory()); + FileUtils.deleteDirectory(extension.getNativesJarStore()); + } catch (IOException e) { + e.printStackTrace(); + } + } } diff --git a/src/main/java/net/fabricmc/loom/task/CleanLoomMappings.java b/src/main/java/net/fabricmc/loom/task/CleanLoomMappings.java index 60569ae..f2121b6 100644 --- a/src/main/java/net/fabricmc/loom/task/CleanLoomMappings.java +++ b/src/main/java/net/fabricmc/loom/task/CleanLoomMappings.java @@ -24,27 +24,29 @@ package net.fabricmc.loom.task; -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.util.DeletingFileVisitor; -import org.gradle.api.Project; -import org.gradle.api.tasks.TaskAction; - import java.io.IOException; import java.nio.file.Files; +import org.gradle.api.Project; +import org.gradle.api.tasks.TaskAction; + +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.util.DeletingFileVisitor; + public class CleanLoomMappings extends AbstractLoomTask { - @TaskAction - public void run() { - Project project = this.getProject(); - LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); - extension.getMappingsProvider().MAPPINGS_TINY.delete(); - extension.getMappingsProvider().MAPPINGS_TINY_BASE.delete(); - extension.getMinecraftMappedProvider().getIntermediaryJar().delete(); - extension.getMinecraftMappedProvider().getMappedJar().delete(); - try { - Files.walkFileTree(extension.getRootProjectBuildCache().toPath(), new DeletingFileVisitor()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } + @TaskAction + public void run() { + Project project = this.getProject(); + LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); + extension.getMappingsProvider().MAPPINGS_TINY.delete(); + extension.getMappingsProvider().MAPPINGS_TINY_BASE.delete(); + extension.getMinecraftMappedProvider().getIntermediaryJar().delete(); + extension.getMinecraftMappedProvider().getMappedJar().delete(); + + try { + Files.walkFileTree(extension.getRootProjectBuildCache().toPath(), new DeletingFileVisitor()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } } diff --git a/src/main/java/net/fabricmc/loom/task/DownloadAssetsTask.java b/src/main/java/net/fabricmc/loom/task/DownloadAssetsTask.java index f43fc40..f4eff67 100644 --- a/src/main/java/net/fabricmc/loom/task/DownloadAssetsTask.java +++ b/src/main/java/net/fabricmc/loom/task/DownloadAssetsTask.java @@ -24,13 +24,14 @@ package net.fabricmc.loom.task; -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.providers.MinecraftAssetsProvider; -import net.fabricmc.loom.providers.MinecraftNativesProvider; +import java.io.IOException; + import org.gradle.api.Project; import org.gradle.api.tasks.TaskAction; -import java.io.IOException; +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.providers.MinecraftAssetsProvider; +import net.fabricmc.loom.providers.MinecraftNativesProvider; public class DownloadAssetsTask extends AbstractLoomTask { @TaskAction diff --git a/src/main/java/net/fabricmc/loom/task/ForkingJavaExecTask.java b/src/main/java/net/fabricmc/loom/task/ForkingJavaExecTask.java index 2d33fea..ab5619a 100644 --- a/src/main/java/net/fabricmc/loom/task/ForkingJavaExecTask.java +++ b/src/main/java/net/fabricmc/loom/task/ForkingJavaExecTask.java @@ -36,18 +36,18 @@ import org.gradle.process.JavaExecSpec; * Simple trait like interface for a Task that wishes to execute a java process * with the classpath of the gradle plugin plus groovy. * - * Created by covers1624 on 11/02/19. + *

Created by covers1624 on 11/02/19. */ public interface ForkingJavaExecTask extends Task { + default ExecResult javaexec(Action action) { + ConfigurationContainer configurations = getProject().getBuildscript().getConfigurations(); + DependencyHandler handler = getProject().getDependencies(); + FileCollection classpath = configurations.getByName("classpath")// + .plus(configurations.detachedConfiguration(handler.localGroovy())); - default ExecResult javaexec(Action action) { - ConfigurationContainer configurations = getProject().getBuildscript().getConfigurations(); - DependencyHandler handler = getProject().getDependencies(); - FileCollection classpath = configurations.getByName("classpath")// - .plus(configurations.detachedConfiguration(handler.localGroovy())); - return getProject().javaexec(spec -> { - spec.classpath(classpath); - action.execute(spec); - }); - } + return getProject().javaexec(spec -> { + spec.classpath(classpath); + action.execute(spec); + }); + } } diff --git a/src/main/java/net/fabricmc/loom/task/GenEclipseRunsTask.java b/src/main/java/net/fabricmc/loom/task/GenEclipseRunsTask.java index 2880eb8..546457c 100644 --- a/src/main/java/net/fabricmc/loom/task/GenEclipseRunsTask.java +++ b/src/main/java/net/fabricmc/loom/task/GenEclipseRunsTask.java @@ -24,33 +24,37 @@ package net.fabricmc.loom.task; -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.util.RunConfig; -import org.apache.commons.io.FileUtils; -import org.gradle.api.tasks.TaskAction; - import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; +import org.apache.commons.io.FileUtils; +import org.gradle.api.tasks.TaskAction; + +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.util.RunConfig; + public class GenEclipseRunsTask extends AbstractLoomTask { + @TaskAction + public void genRuns() throws IOException { + File clientRunConfigs = new File(getProject().getRootDir(), getProject().getName() + "_client.launch"); + File serverRunConfigs = new File(getProject().getRootDir(), getProject().getName() + "_server.launch"); - @TaskAction - public void genRuns() throws IOException { - File clientRunConfigs = new File(getProject().getRootDir(), getProject().getName() + "_client.launch"); - File serverRunConfigs = new File(getProject().getRootDir(), getProject().getName() + "_server.launch"); + String clientRunConfig = RunConfig.clientRunConfig(getProject()).fromDummy("eclipse_run_config_template.xml"); + String serverRunConfig = RunConfig.serverRunConfig(getProject()).fromDummy("eclipse_run_config_template.xml"); - String clientRunConfig = RunConfig.clientRunConfig(getProject()).fromDummy("eclipse_run_config_template.xml"); - String serverRunConfig = RunConfig.serverRunConfig(getProject()).fromDummy("eclipse_run_config_template.xml"); + if (!clientRunConfigs.exists()) { + FileUtils.writeStringToFile(clientRunConfigs, clientRunConfig, StandardCharsets.UTF_8); + } - if(!clientRunConfigs.exists()) - FileUtils.writeStringToFile(clientRunConfigs, clientRunConfig, StandardCharsets.UTF_8); - if(!serverRunConfigs.exists()) - FileUtils.writeStringToFile(serverRunConfigs, serverRunConfig, StandardCharsets.UTF_8); + if (!serverRunConfigs.exists()) { + FileUtils.writeStringToFile(serverRunConfigs, serverRunConfig, StandardCharsets.UTF_8); + } - File runDir = new File(getProject().getRootDir(), this.getProject().getExtensions().getByType(LoomGradleExtension.class).runDir); - if(!runDir.exists()) - runDir.mkdirs(); - } + File runDir = new File(getProject().getRootDir(), this.getProject().getExtensions().getByType(LoomGradleExtension.class).runDir); + if (!runDir.exists()) { + runDir.mkdirs(); + } + } } diff --git a/src/main/java/net/fabricmc/loom/task/GenIdeaProjectTask.java b/src/main/java/net/fabricmc/loom/task/GenIdeaProjectTask.java index 34a1bf5..a5d5775 100644 --- a/src/main/java/net/fabricmc/loom/task/GenIdeaProjectTask.java +++ b/src/main/java/net/fabricmc/loom/task/GenIdeaProjectTask.java @@ -24,15 +24,8 @@ package net.fabricmc.loom.task; -import net.fabricmc.loom.AbstractPlugin; -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.util.RunConfig; -import org.gradle.api.Project; -import org.gradle.api.tasks.TaskAction; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; +import java.io.File; +import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -43,18 +36,28 @@ import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; -import java.io.File; -import java.io.IOException; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; +import org.gradle.api.Project; +import org.gradle.api.tasks.TaskAction; + +import net.fabricmc.loom.AbstractPlugin; +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.util.RunConfig; public class GenIdeaProjectTask extends AbstractLoomTask { - @TaskAction public void genIdeaRuns() throws IOException, ParserConfigurationException, SAXException, TransformerException { Project project = this.getProject(); + //Only generate the idea runs on the root project - if(!AbstractPlugin.isRootProject(project)){ + if (!AbstractPlugin.isRootProject(project)) { return; } + LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); project.getLogger().lifecycle(":Building idea workspace"); @@ -65,8 +68,10 @@ public class GenIdeaProjectTask extends AbstractLoomTask { NodeList list = doc.getElementsByTagName("component"); Element runManager = null; + for (int i = 0; i < list.getLength(); i++) { Element element = (Element) list.item(i); + if (element.getAttribute("name").equals("RunManager")) { runManager = element; break; @@ -89,6 +94,7 @@ public class GenIdeaProjectTask extends AbstractLoomTask { transformer.transform(source, result); File runDir = new File(getProject().getRootDir(), extension.runDir); + if (!runDir.exists()) { runDir.mkdirs(); } diff --git a/src/main/java/net/fabricmc/loom/task/GenVsCodeProjectTask.java b/src/main/java/net/fabricmc/loom/task/GenVsCodeProjectTask.java index aa64562..63d10d2 100644 --- a/src/main/java/net/fabricmc/loom/task/GenVsCodeProjectTask.java +++ b/src/main/java/net/fabricmc/loom/task/GenVsCodeProjectTask.java @@ -24,81 +24,85 @@ package net.fabricmc.loom.task; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.util.RunConfig; -import org.apache.commons.io.FileUtils; -import org.gradle.api.tasks.TaskAction; - import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import org.apache.commons.io.FileUtils; +import org.gradle.api.tasks.TaskAction; + +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.util.RunConfig; + //Recommended vscode plugins: // https://marketplace.visualstudio.com/items?itemName=redhat.java // https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-debug // https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-pack public class GenVsCodeProjectTask extends AbstractLoomTask { + @TaskAction + public void genRuns() { + LoomGradleExtension extension = getProject().getExtensions().getByType(LoomGradleExtension.class); + File projectDir = getProject().file(".vscode"); - @TaskAction - public void genRuns() { - LoomGradleExtension extension = getProject().getExtensions().getByType(LoomGradleExtension.class); - File projectDir = getProject().file(".vscode"); - if (!projectDir.exists()) { - projectDir.mkdir(); - } - File launchJson = new File(projectDir, "launch.json"); - if (launchJson.exists()) { - launchJson.delete(); - } + if (!projectDir.exists()) { + projectDir.mkdir(); + } - VsCodeLaunch launch = new VsCodeLaunch(); - launch.add(RunConfig.clientRunConfig(getProject())); - launch.add(RunConfig.serverRunConfig(getProject())); + File launchJson = new File(projectDir, "launch.json"); - Gson gson = new GsonBuilder().setPrettyPrinting().create(); - String json = gson.toJson(launch); + if (launchJson.exists()) { + launchJson.delete(); + } - try { - FileUtils.writeStringToFile(launchJson, json, StandardCharsets.UTF_8); - } catch (IOException e) { - throw new RuntimeException("Failed to write launch.json", e); - } + VsCodeLaunch launch = new VsCodeLaunch(); + launch.add(RunConfig.clientRunConfig(getProject())); + launch.add(RunConfig.serverRunConfig(getProject())); - File runDir = new File(getProject().getRootDir(), extension.runDir); - if (!runDir.exists()) { - runDir.mkdirs(); - } - } + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + String json = gson.toJson(launch); - private static class VsCodeLaunch { - public String version = "0.2.0"; - public List configurations = new ArrayList<>(); + try { + FileUtils.writeStringToFile(launchJson, json, StandardCharsets.UTF_8); + } catch (IOException e) { + throw new RuntimeException("Failed to write launch.json", e); + } - public void add(RunConfig runConfig) { - configurations.add(new VsCodeConfiguration(runConfig)); - } - } + File runDir = new File(getProject().getRootDir(), extension.runDir); - private static class VsCodeConfiguration { - public String type = "java"; - public String name; - public String request = "launch"; - public String cwd = "${workspaceFolder}/run"; - public String console = "internalConsole"; - public boolean stopOnEntry = false; - public String mainClass; - public String vmArgs; - public String args; + if (!runDir.exists()) { + runDir.mkdirs(); + } + } - public VsCodeConfiguration(RunConfig runConfig) { - this.name = runConfig.configName; - this.mainClass = runConfig.mainClass; - this.vmArgs = runConfig.vmArgs; - this.args = runConfig.programArgs; - } - } + private static class VsCodeLaunch { + public String version = "0.2.0"; + public List configurations = new ArrayList<>(); + + public void add(RunConfig runConfig) { + configurations.add(new VsCodeConfiguration(runConfig)); + } + } + + private static class VsCodeConfiguration { + public String type = "java"; + public String name; + public String request = "launch"; + public String cwd = "${workspaceFolder}/run"; + public String console = "internalConsole"; + public boolean stopOnEntry = false; + public String mainClass; + public String vmArgs; + public String args; + + VsCodeConfiguration(RunConfig runConfig) { + this.name = runConfig.configName; + this.mainClass = runConfig.mainClass; + this.vmArgs = runConfig.vmArgs; + this.args = runConfig.programArgs; + } + } } diff --git a/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java b/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java index cc18fa7..35ef071 100644 --- a/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java +++ b/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java @@ -24,10 +24,12 @@ package net.fabricmc.loom.task; -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.util.Constants; -import net.fabricmc.loom.util.Version; -import net.fabricmc.mappings.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + import org.cadixdev.lorenz.MappingSet; import org.cadixdev.lorenz.io.MappingsReader; import org.cadixdev.mercury.Mercury; @@ -35,149 +37,147 @@ import org.cadixdev.mercury.remapper.MercuryRemapper; import org.gradle.api.Project; import org.gradle.api.tasks.TaskAction; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; +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; public class MigrateMappingsTask extends AbstractLoomTask { - @TaskAction - public void doTask() throws Throwable { - Project project = getProject(); - LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); - Map properties = project.getProperties(); + @TaskAction + public void doTask() throws Throwable { + Project project = getProject(); + LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); + Map properties = project.getProperties(); - project.getLogger().lifecycle(":loading mappings"); + project.getLogger().lifecycle(":loading mappings"); - File mappingsFile = null; + File mappingsFile = null; - 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 (properties.containsKey("targetMappingsFile")) { + mappingsFile = new File((String) properties.get("targetMappingsFile")); + } else if (properties.containsKey("targetMappingsArtifact")) { + String[] artifactName = ((String) properties.get("targetMappingsArtifact")).split(":"); - String mappingsName = artifactName[0] + "." + artifactName[1]; + if (artifactName.length != 3) { + throw new RuntimeException("Invalid artifact name: " + properties.get("targetMappingsArtifact")); + } - Version v = new Version(artifactName[2]); - String minecraftVersion = v.getMinecraftVersion(); - String mappingsVersion = v.getMappingsVersion(); + String mappingsName = artifactName[0] + "." + artifactName[1]; - mappingsFile = new File(extension.getMappingsProvider().MAPPINGS_DIR, mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion); - } + Version v = new Version(artifactName[2]); + String minecraftVersion = v.getMinecraftVersion(); + String mappingsVersion = v.getMappingsVersion(); - if (mappingsFile == null || !mappingsFile.exists()) { - throw new RuntimeException("Could not find mappings file: " + (mappingsFile != null ? mappingsFile : "null")); - } + mappingsFile = new File(extension.getMappingsProvider().MAPPINGS_DIR, mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion); + } - if (!properties.containsKey("inputDir") || !properties.containsKey("outputDir")) { - throw new RuntimeException("Must specify input and output dir!"); - } + if (mappingsFile == null || !mappingsFile.exists()) { + throw new RuntimeException("Could not find mappings file: " + (mappingsFile != null ? mappingsFile : "null")); + } - File inputDir = new File((String) properties.get("inputDir")); - File outputDir = new File((String) properties.get("outputDir")); + if (!properties.containsKey("inputDir") || !properties.containsKey("outputDir")) { + throw new RuntimeException("Must specify input and output dir!"); + } - if (!inputDir.exists() || !inputDir.isDirectory()) { - throw new RuntimeException("Could not find input directory: " + inputDir); - } + File inputDir = new File((String) properties.get("inputDir")); + File outputDir = new File((String) properties.get("outputDir")); - if (!outputDir.exists()) { - if (!outputDir.mkdirs()) { - throw new RuntimeException("Could not create output directory:" + outputDir); - } - } + if (!inputDir.exists() || !inputDir.isDirectory()) { + throw new RuntimeException("Could not find input directory: " + inputDir); + } - Mappings sourceMappings = extension.getMappingsProvider().getMappings(); - Mappings targetMappings; + if (!outputDir.exists()) { + if (!outputDir.mkdirs()) { + throw new RuntimeException("Could not create output directory:" + outputDir); + } + } - try (FileInputStream stream = new FileInputStream(mappingsFile)) { - targetMappings = net.fabricmc.mappings.MappingsProvider.readTinyMappings(stream, false); - } + Mappings sourceMappings = extension.getMappingsProvider().getMappings(); + Mappings targetMappings; - project.getLogger().lifecycle(":joining mappings"); - MappingSet mappingSet = new MappingsJoiner(sourceMappings, targetMappings, "intermediary", "named").read(); + try (FileInputStream stream = new FileInputStream(mappingsFile)) { + targetMappings = net.fabricmc.mappings.MappingsProvider.readTinyMappings(stream, false); + } - project.getLogger().lifecycle(":remapping"); - Mercury mercury = new Mercury(); + project.getLogger().lifecycle(":joining mappings"); + MappingSet mappingSet = new MappingsJoiner(sourceMappings, targetMappings, "intermediary", "named").read(); - for (File file : project.getConfigurations().getByName(Constants.MINECRAFT_DEPENDENCIES).getFiles()) { - mercury.getClassPath().add(file.toPath()); - } + project.getLogger().lifecycle(":remapping"); + Mercury mercury = new Mercury(); - for (File file : project.getConfigurations().getByName("compileClasspath").getFiles()) { - mercury.getClassPath().add(file.toPath()); - } + for (File file : project.getConfigurations().getByName(Constants.MINECRAFT_DEPENDENCIES).getFiles()) { + mercury.getClassPath().add(file.toPath()); + } - mercury.getClassPath().add(extension.getMinecraftMappedProvider().MINECRAFT_MAPPED_JAR.toPath()); - mercury.getClassPath().add(extension.getMinecraftMappedProvider().MINECRAFT_INTERMEDIARY_JAR.toPath()); + for (File file : project.getConfigurations().getByName("compileClasspath").getFiles()) { + mercury.getClassPath().add(file.toPath()); + } - mercury.getProcessors().add(MercuryRemapper.create(mappingSet)); + mercury.getClassPath().add(extension.getMinecraftMappedProvider().MINECRAFT_MAPPED_JAR.toPath()); + mercury.getClassPath().add(extension.getMinecraftMappedProvider().MINECRAFT_INTERMEDIARY_JAR.toPath()); - try { - mercury.rewrite(inputDir.toPath(), outputDir.toPath()); - } catch (Exception e) { - project.getLogger().warn("Could not remap fully!", e); - } + mercury.getProcessors().add(MercuryRemapper.create(mappingSet)); - project.getLogger().lifecycle(":cleaning file descriptors"); - System.gc(); - } + try { + mercury.rewrite(inputDir.toPath(), outputDir.toPath()); + } catch (Exception e) { + project.getLogger().warn("Could not remap fully!", e); + } - public static class MappingsJoiner extends MappingsReader { - private final Mappings sourceMappings, targetMappings; - private final String fromNamespace, toNamespace; + project.getLogger().lifecycle(":cleaning file descriptors"); + System.gc(); + } - public MappingsJoiner(Mappings sourceMappings, Mappings targetMappings, String fromNamespace, String toNamespace) { - this.sourceMappings = sourceMappings; - this.targetMappings = targetMappings; - this.fromNamespace = fromNamespace; - this.toNamespace = toNamespace; - } + public static class MappingsJoiner extends MappingsReader { + private final Mappings sourceMappings, targetMappings; + private final String fromNamespace, toNamespace; - @Override - public MappingSet read(MappingSet mappings) throws IOException { - Map targetClasses = new HashMap<>(); - Map targetFields = new HashMap<>(); - Map targetMethods = new HashMap<>(); + public MappingsJoiner(Mappings sourceMappings, Mappings targetMappings, String fromNamespace, String toNamespace) { + this.sourceMappings = sourceMappings; + this.targetMappings = targetMappings; + this.fromNamespace = fromNamespace; + this.toNamespace = toNamespace; + } - 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)); + @Override + public MappingSet read(MappingSet mappings) throws IOException { + Map targetClasses = new HashMap<>(); + Map targetFields = new HashMap<>(); + Map targetMethods = new HashMap<>(); - for (ClassEntry entry : sourceMappings.getClassEntries()) { - String from = entry.get(toNamespace); - String to = targetClasses.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace); + 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)); - mappings.getOrCreateClassMapping(from).setDeobfuscatedName(to); - } + for (ClassEntry entry : sourceMappings.getClassEntries()) { + String from = entry.get(toNamespace); + String to = targetClasses.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace); - for (FieldEntry entry : sourceMappings.getFieldEntries()) { - EntryTriple fromEntry = entry.get(toNamespace); - EntryTriple toEntry = targetFields.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace); + mappings.getOrCreateClassMapping(from).setDeobfuscatedName(to); + } - mappings.getOrCreateClassMapping(fromEntry.getOwner()) - .getOrCreateFieldMapping(fromEntry.getName(), fromEntry.getDesc()) - .setDeobfuscatedName(toEntry.getName()); - } + for (FieldEntry entry : sourceMappings.getFieldEntries()) { + EntryTriple fromEntry = entry.get(toNamespace); + EntryTriple toEntry = targetFields.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace); - for (MethodEntry entry : sourceMappings.getMethodEntries()) { - EntryTriple fromEntry = entry.get(toNamespace); - EntryTriple toEntry = targetMethods.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace); + mappings.getOrCreateClassMapping(fromEntry.getOwner()).getOrCreateFieldMapping(fromEntry.getName(), fromEntry.getDesc()).setDeobfuscatedName(toEntry.getName()); + } - mappings.getOrCreateClassMapping(fromEntry.getOwner()) - .getOrCreateMethodMapping(fromEntry.getName(), fromEntry.getDesc()) - .setDeobfuscatedName(toEntry.getName()); - } + for (MethodEntry entry : sourceMappings.getMethodEntries()) { + EntryTriple fromEntry = entry.get(toNamespace); + EntryTriple toEntry = targetMethods.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace); - return mappings; - } + mappings.getOrCreateClassMapping(fromEntry.getOwner()).getOrCreateMethodMapping(fromEntry.getName(), fromEntry.getDesc()).setDeobfuscatedName(toEntry.getName()); + } - @Override - public void close() throws IOException { + return mappings; + } - } - } + @Override + public void close() throws IOException { } + } } diff --git a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java index aa4f1a0..3936fc6 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java +++ b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java @@ -24,6 +24,21 @@ package net.fabricmc.loom.task; +import java.io.File; +import java.io.FileNotFoundException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.gradle.api.Project; +import org.gradle.api.file.RegularFileProperty; +import org.gradle.api.provider.Property; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.InputFile; +import org.gradle.api.tasks.TaskAction; +import org.gradle.jvm.tasks.Jar; + import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.providers.MappingsProvider; import net.fabricmc.loom.util.GradleSupport; @@ -33,21 +48,6 @@ import net.fabricmc.loom.util.TinyRemapperMappingsHelper; import net.fabricmc.tinyremapper.OutputConsumerPath; import net.fabricmc.tinyremapper.TinyRemapper; import net.fabricmc.tinyremapper.TinyUtils; -import org.gradle.api.Project; -import org.gradle.api.file.RegularFile; -import org.gradle.api.file.RegularFileProperty; -import org.gradle.api.provider.Property; -import org.gradle.api.tasks.Input; -import org.gradle.api.tasks.InputFile; -import org.gradle.api.tasks.TaskAction; -import org.gradle.jvm.tasks.Jar; - -import java.io.File; -import java.io.FileNotFoundException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.LinkedHashSet; -import java.util.Set; public class RemapJarTask extends Jar { private RegularFileProperty input; @@ -86,6 +86,7 @@ public class RemapJarTask extends Jar { TinyRemapper.Builder remapperBuilder = TinyRemapper.newRemapper(); remapperBuilder = remapperBuilder.withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM)); + if (mixinMapFile.exists()) { remapperBuilder = remapperBuilder.withMappings(TinyUtils.createTinyMappingProvider(mixinMapPath, fromM, toM)); } @@ -93,9 +94,11 @@ public class RemapJarTask extends Jar { project.getLogger().lifecycle(":remapping " + input.getFileName()); StringBuilder rc = new StringBuilder("Remap classpath: "); + for (Path p : classpath) { rc.append("\n - ").append(p.toString()); } + project.getLogger().debug(rc.toString()); TinyRemapper remapper = remapperBuilder.build(); diff --git a/src/main/java/net/fabricmc/loom/task/RemapLineNumbersTask.java b/src/main/java/net/fabricmc/loom/task/RemapLineNumbersTask.java index 5317d1c..b926a71 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapLineNumbersTask.java +++ b/src/main/java/net/fabricmc/loom/task/RemapLineNumbersTask.java @@ -24,51 +24,68 @@ package net.fabricmc.loom.task; -import net.fabricmc.loom.task.fernflower.FernFlowerTask; -import net.fabricmc.loom.util.LineNumberRemapper; -import net.fabricmc.loom.util.progress.ProgressLogger; -import net.fabricmc.stitch.util.StitchUtil; +import java.io.File; +import java.io.IOException; + import org.gradle.api.Project; -import org.gradle.api.tasks.Input; import org.gradle.api.tasks.InputFile; import org.gradle.api.tasks.OutputFile; import org.gradle.api.tasks.TaskAction; -import java.io.File; -import java.io.IOException; +import net.fabricmc.loom.task.fernflower.FernFlowerTask; +import net.fabricmc.loom.util.LineNumberRemapper; +import net.fabricmc.loom.util.progress.ProgressLogger; +import net.fabricmc.stitch.util.StitchUtil; public class RemapLineNumbersTask extends AbstractLoomTask { - private Object input; - private Object output; - private Object lineMapFile; + private Object input; + private Object output; + private Object lineMapFile; - @TaskAction - public void doTask() throws Throwable { - Project project = getProject(); + @TaskAction + public void doTask() throws Throwable { + Project project = getProject(); - project.getLogger().lifecycle(":adjusting line numbers"); - LineNumberRemapper remapper = new LineNumberRemapper(); - remapper.readMappings(getLineMapFile()); + project.getLogger().lifecycle(":adjusting line numbers"); + LineNumberRemapper remapper = new LineNumberRemapper(); + remapper.readMappings(getLineMapFile()); - ProgressLogger progressLogger = ProgressLogger.getProgressFactory(project, FernFlowerTask.class.getName()); - progressLogger.start("Adjusting line numbers", "linemap"); + ProgressLogger progressLogger = ProgressLogger.getProgressFactory(project, FernFlowerTask.class.getName()); + progressLogger.start("Adjusting line numbers", "linemap"); - try (StitchUtil.FileSystemDelegate inFs = StitchUtil.getJarFileSystem(getInput(), true); - StitchUtil.FileSystemDelegate outFs = StitchUtil.getJarFileSystem(getOutput(), true)) { - remapper.process(progressLogger, inFs.get().getPath("/"), outFs.get().getPath("/")); - } catch (IOException e) { - throw new RuntimeException(e); - } + try (StitchUtil.FileSystemDelegate inFs = StitchUtil.getJarFileSystem(getInput(), true); StitchUtil.FileSystemDelegate outFs = StitchUtil.getJarFileSystem(getOutput(), true)) { + remapper.process(progressLogger, inFs.get().getPath("/"), outFs.get().getPath("/")); + } catch (IOException e) { + throw new RuntimeException(e); + } - progressLogger.completed(); - } + progressLogger.completed(); + } - //@formatter:off - @InputFile public File getInput() { return getProject().file(input); } - @InputFile public File getLineMapFile() { return getProject().file(lineMapFile); } - @OutputFile public File getOutput() { return getProject().file(output); } - public void setInput(Object input) { this.input = input; } - public void setLineMapFile(Object lineMapFile) { this.lineMapFile = lineMapFile; } - public void setOutput(Object output) { this.output = output; } - //@formatter:on + @InputFile + public File getInput() { + return getProject().file(input); + } + + @InputFile + public File getLineMapFile() { + return getProject().file(lineMapFile); + } + + @OutputFile + public File getOutput() { + return getProject().file(output); + } + + public void setInput(Object input) { + this.input = input; + } + + public void setLineMapFile(Object lineMapFile) { + this.lineMapFile = lineMapFile; + } + + public void setOutput(Object output) { + this.output = output; + } } diff --git a/src/main/java/net/fabricmc/loom/task/RemapSourcesJarTask.java b/src/main/java/net/fabricmc/loom/task/RemapSourcesJarTask.java index ee5ae58..9a4b8e3 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapSourcesJarTask.java +++ b/src/main/java/net/fabricmc/loom/task/RemapSourcesJarTask.java @@ -24,13 +24,14 @@ package net.fabricmc.loom.task; -import net.fabricmc.loom.util.SourceRemapper; +import java.io.File; + import org.gradle.api.tasks.Input; import org.gradle.api.tasks.InputFile; import org.gradle.api.tasks.OutputFile; import org.gradle.api.tasks.TaskAction; -import java.io.File; +import net.fabricmc.loom.util.SourceRemapper; public class RemapSourcesJarTask extends AbstractLoomTask { private Object input; @@ -42,13 +43,30 @@ public class RemapSourcesJarTask extends AbstractLoomTask { SourceRemapper.remapSources(getProject(), getInput(), getOutput(), direction.equals("named")); } - //@formatter:off @InputFile - public File getInput() { return getProject().file(input); } - @OutputFile public File getOutput() { return getProject().file(output == null ? input : output); } - @Input public String getTargetNamespace() { return direction; } - public void setInput(Object input) { this.input = input; } - public void setOutput(Object output) { this.output = output; } - public void setTargetNamespace(String value) { this.direction = value; } - //@formatter:on + public File getInput() { + return getProject().file(input); + } + + @OutputFile + public File getOutput() { + return getProject().file(output == null ? input : output); + } + + @Input + public String getTargetNamespace() { + return direction; + } + + public void setInput(Object input) { + this.input = input; + } + + public void setOutput(Object output) { + this.output = output; + } + + public void setTargetNamespace(String value) { + this.direction = value; + } } diff --git a/src/main/java/net/fabricmc/loom/task/fernflower/FernFlowerTask.java b/src/main/java/net/fabricmc/loom/task/fernflower/FernFlowerTask.java index f962f25..24c2514 100644 --- a/src/main/java/net/fabricmc/loom/task/fernflower/FernFlowerTask.java +++ b/src/main/java/net/fabricmc/loom/task/fernflower/FernFlowerTask.java @@ -24,123 +24,140 @@ package net.fabricmc.loom.task.fernflower; -import net.fabricmc.loom.task.AbstractDecompileTask; -import net.fabricmc.loom.task.ForkingJavaExecTask; -import net.fabricmc.loom.util.ConsumingOutputStream; -import org.gradle.api.file.FileCollection; +import static java.text.MessageFormat.format; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; +import java.util.function.Supplier; + +import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.gradle.api.internal.project.ProjectInternal; import org.gradle.api.logging.LogLevel; import org.gradle.api.tasks.Input; -import org.gradle.api.tasks.OutputFile; import org.gradle.api.tasks.TaskAction; import org.gradle.internal.logging.progress.ProgressLogger; import org.gradle.internal.logging.progress.ProgressLoggerFactory; import org.gradle.internal.service.ServiceRegistry; import org.gradle.process.ExecResult; -import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; -import java.io.File; +import net.fabricmc.loom.task.AbstractDecompileTask; +import net.fabricmc.loom.task.ForkingJavaExecTask; +import net.fabricmc.loom.util.ConsumingOutputStream; import net.fabricmc.loom.util.OperatingSystem; -import java.util.*; -import java.util.function.Supplier; - -import static java.text.MessageFormat.format; /** * Created by covers1624 on 9/02/19. */ public class FernFlowerTask extends AbstractDecompileTask implements ForkingJavaExecTask { + private boolean noFork = false; + private int numThreads = Runtime.getRuntime().availableProcessors(); - private boolean noFork = false; - private int numThreads = Runtime.getRuntime().availableProcessors(); + @TaskAction + public void doTask() throws Throwable { + if (!OperatingSystem.is64Bit()) { + throw new UnsupportedOperationException("FernFlowerTask requires a 64bit JVM to run due to the memory requirements"); + } - @TaskAction - public void doTask() throws Throwable { - if(!OperatingSystem.is64Bit()){ - throw new UnsupportedOperationException("FernFlowerTask requires a 64bit JVM to run due to the memory requirements"); - } + Map options = new HashMap<>(); + options.put(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES, "1"); + options.put(IFernflowerPreferences.BYTECODE_SOURCE_MAPPING, "1"); + options.put(IFernflowerPreferences.LOG_LEVEL, "trace"); + getLogging().captureStandardOutput(LogLevel.LIFECYCLE); - Map options = new HashMap<>(); - options.put(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES, "1"); - options.put(IFernflowerPreferences.BYTECODE_SOURCE_MAPPING, "1"); - options.put(IFernflowerPreferences.LOG_LEVEL, "trace"); - getLogging().captureStandardOutput(LogLevel.LIFECYCLE); + List args = new ArrayList<>(); - List args = new ArrayList<>(); + options.forEach((k, v) -> args.add(format("-{0}={1}", k, v))); + args.add(getInput().getAbsolutePath()); + args.add("-o=" + getOutput().getAbsolutePath()); - options.forEach((k, v) -> args.add(format("-{0}={1}", k, v))); - args.add(getInput().getAbsolutePath()); - args.add("-o=" + getOutput().getAbsolutePath()); - if (getLineMapFile() != null) { - args.add("-l=" + getLineMapFile().getAbsolutePath()); - } - args.add("-t=" + getNumThreads()); + if (getLineMapFile() != null) { + args.add("-l=" + getLineMapFile().getAbsolutePath()); + } - //TODO, Decompiler breaks on jemalloc, J9 module-info.class? - getLibraries().forEach(f -> args.add("-e=" + f.getAbsolutePath())); + args.add("-t=" + getNumThreads()); - ServiceRegistry registry = ((ProjectInternal) getProject()).getServices(); - ProgressLoggerFactory factory = registry.get(ProgressLoggerFactory.class); - ProgressLogger progressGroup = factory.newOperation(getClass()).setDescription("Decompile"); - Supplier loggerFactory = () -> { - ProgressLogger pl = factory.newOperation(getClass(), progressGroup); - pl.setDescription("decompile worker"); - pl.started(); - return pl; - }; - Stack freeLoggers = new Stack<>(); - Map inUseLoggers = new HashMap<>(); + //TODO, Decompiler breaks on jemalloc, J9 module-info.class? + getLibraries().forEach(f -> args.add("-e=" + f.getAbsolutePath())); - progressGroup.started(); - ExecResult result = javaexec(spec -> { - spec.setMain(ForkedFFExecutor.class.getName()); - spec.jvmArgs("-Xms200m", "-Xmx3G"); - spec.setArgs(args); - spec.setErrorOutput(System.err); - spec.setStandardOutput(new ConsumingOutputStream(line -> { - if (line.startsWith("Listening for transport") || !line.contains("::")) { - System.out.println(line); - return; - } + ServiceRegistry registry = ((ProjectInternal) getProject()).getServices(); + ProgressLoggerFactory factory = registry.get(ProgressLoggerFactory.class); + ProgressLogger progressGroup = factory.newOperation(getClass()).setDescription("Decompile"); + Supplier loggerFactory = () -> { + ProgressLogger pl = factory.newOperation(getClass(), progressGroup); + pl.setDescription("decompile worker"); + pl.started(); + return pl; + }; + Stack freeLoggers = new Stack<>(); + Map inUseLoggers = new HashMap<>(); - int sepIdx = line.indexOf("::"); - String id = line.substring(0, sepIdx).trim(); - String data = line.substring(sepIdx + 2).trim(); + progressGroup.started(); + ExecResult result = javaexec(spec -> { + spec.setMain(ForkedFFExecutor.class.getName()); + spec.jvmArgs("-Xms200m", "-Xmx3G"); + spec.setArgs(args); + spec.setErrorOutput(System.err); + spec.setStandardOutput(new ConsumingOutputStream(line -> { + if (line.startsWith("Listening for transport") || !line.contains("::")) { + System.out.println(line); + return; + } - ProgressLogger logger = inUseLoggers.get(id); + int sepIdx = line.indexOf("::"); + String id = line.substring(0, sepIdx).trim(); + String data = line.substring(sepIdx + 2).trim(); - String[] segs = data.split(" "); - if (segs[0].equals("waiting")) { - if (logger != null) { - logger.progress("Idle.."); - inUseLoggers.remove(id); - freeLoggers.push(logger); - } - } else { - if (logger == null) { - if (!freeLoggers.isEmpty()) { - logger = freeLoggers.pop(); - } else { - logger = loggerFactory.get(); - } - inUseLoggers.put(id, logger); - } - logger.progress(data); - } - })); - }); - inUseLoggers.values().forEach(ProgressLogger::completed); - freeLoggers.forEach(ProgressLogger::completed); - progressGroup.completed(); + ProgressLogger logger = inUseLoggers.get(id); - result.rethrowFailure(); - result.assertNormalExitValue(); - } + String[] segs = data.split(" "); - //@formatter:off - @Input public int getNumThreads() { return numThreads; } - @Input public boolean isNoFork() { return noFork; } - public void setNoFork(boolean noFork) { this.noFork = noFork; } - public void setNumThreads(int numThreads) { this.numThreads = numThreads; } - //@formatter:on + if (segs[0].equals("waiting")) { + if (logger != null) { + logger.progress("Idle.."); + inUseLoggers.remove(id); + freeLoggers.push(logger); + } + } else { + if (logger == null) { + if (!freeLoggers.isEmpty()) { + logger = freeLoggers.pop(); + } else { + logger = loggerFactory.get(); + } + + inUseLoggers.put(id, logger); + } + + logger.progress(data); + } + })); + }); + inUseLoggers.values().forEach(ProgressLogger::completed); + freeLoggers.forEach(ProgressLogger::completed); + progressGroup.completed(); + + result.rethrowFailure(); + result.assertNormalExitValue(); + } + + @Input + public int getNumThreads() { + return numThreads; + } + + @Input + public boolean isNoFork() { + return noFork; + } + + public void setNoFork(boolean noFork) { + this.noFork = noFork; + } + + public void setNumThreads(int numThreads) { + this.numThreads = numThreads; + } } diff --git a/src/main/java/net/fabricmc/loom/task/fernflower/FernFlowerUtils.java b/src/main/java/net/fabricmc/loom/task/fernflower/FernFlowerUtils.java index 83af198..69c0e70 100644 --- a/src/main/java/net/fabricmc/loom/task/fernflower/FernFlowerUtils.java +++ b/src/main/java/net/fabricmc/loom/task/fernflower/FernFlowerUtils.java @@ -24,26 +24,29 @@ package net.fabricmc.loom.task.fernflower; -import org.jetbrains.java.decompiler.util.InterpreterUtil; - import java.io.File; import java.io.IOException; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; +import org.jetbrains.java.decompiler.util.InterpreterUtil; + public class FernFlowerUtils { public static byte[] getBytecode(String externalPath, String internalPath) throws IOException { - File file = new File(externalPath); - if (internalPath == null) { - return InterpreterUtil.getBytes(file); - } else { - try (ZipFile archive = new ZipFile(file)) { - ZipEntry entry = archive.getEntry(internalPath); - if (entry == null) { - throw new IOException("Entry not found: " + internalPath); - } - return InterpreterUtil.getBytes(archive, entry); - } - } + File file = new File(externalPath); + + if (internalPath == null) { + return InterpreterUtil.getBytes(file); + } else { + try (ZipFile archive = new ZipFile(file)) { + ZipEntry entry = archive.getEntry(internalPath); + + if (entry == null) { + throw new IOException("Entry not found: " + internalPath); + } + + return InterpreterUtil.getBytes(archive, entry); + } + } } } diff --git a/src/main/java/net/fabricmc/loom/task/fernflower/ForkedFFExecutor.java b/src/main/java/net/fabricmc/loom/task/fernflower/ForkedFFExecutor.java index 287c799..b2374b3 100644 --- a/src/main/java/net/fabricmc/loom/task/fernflower/ForkedFFExecutor.java +++ b/src/main/java/net/fabricmc/loom/task/fernflower/ForkedFFExecutor.java @@ -24,82 +24,92 @@ package net.fabricmc.loom.task.fernflower; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + import org.jetbrains.java.decompiler.main.Fernflower; import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; import org.jetbrains.java.decompiler.main.extern.IResultSaver; -import java.io.File; -import java.io.IOException; -import java.util.*; - /** * Entry point for Forked FernFlower task. * Takes one parameter, a single file, each line is treated as command line input. * Forces one input file. * Forces one output file using '-o=/path/to/output' - * * Created by covers1624 on 11/02/19. */ public class ForkedFFExecutor { + public static void main(String[] args) throws IOException { + Map options = new HashMap<>(); + File input = null; + File output = null; + File lineMap = null; + List libraries = new ArrayList<>(); + int numThreads = 0; - public static void main(String[] args) throws IOException { - Map options = new HashMap<>(); - File input = null; - File output = null; - File lineMap = null; - List libraries = new ArrayList<>(); - int numThreads = 0; + boolean isOption = true; - boolean isOption = true; - for (String arg : args) { - if (isOption && arg.length() > 5 && arg.charAt(0) == '-' && arg.charAt(4) == '=') { - String value = arg.substring(5); - if ("true".equalsIgnoreCase(value)) { - value = "1"; - } else if ("false".equalsIgnoreCase(value)) { - value = "0"; - } + for (String arg : args) { + if (isOption && arg.length() > 5 && arg.charAt(0) == '-' && arg.charAt(4) == '=') { + String value = arg.substring(5); - options.put(arg.substring(1, 4), value); - } else { - isOption = false; - if (arg.startsWith("-e=")) { - libraries.add(new File(arg.substring(3))); - } else if (arg.startsWith("-o=")) { - if (output != null) { - throw new RuntimeException("Unable to set more than one output."); - } - output = new File(arg.substring(3)); - } else if (arg.startsWith("-l=")) { - if (lineMap != null) { - throw new RuntimeException("Unable to set more than one lineMap file."); - } - lineMap = new File(arg.substring(3)); - } else if (arg.startsWith("-t=")) { - numThreads = Integer.parseInt(arg.substring(3)); - } else { - if (input != null) { - throw new RuntimeException("Unable to set more than one input."); - } - input = new File(arg); - } - } - } + if ("true".equalsIgnoreCase(value)) { + value = "1"; + } else if ("false".equalsIgnoreCase(value)) { + value = "0"; + } - Objects.requireNonNull(input, "Input not set."); - Objects.requireNonNull(output, "Output not set."); + options.put(arg.substring(1, 4), value); + } else { + isOption = false; - runFF(options, libraries, input, output, lineMap); - } + if (arg.startsWith("-e=")) { + libraries.add(new File(arg.substring(3))); + } else if (arg.startsWith("-o=")) { + if (output != null) { + throw new RuntimeException("Unable to set more than one output."); + } - public static void runFF(Map options, List libraries, File input, File output, File lineMap) { - IResultSaver saver = new ThreadSafeResultSaver(() -> output, () -> lineMap); - IFernflowerLogger logger = new ThreadIDFFLogger(); - Fernflower ff = new Fernflower(FernFlowerUtils::getBytecode, saver, options, logger); - for (File library : libraries) { - ff.addLibrary(library); - } - ff.addSource(input); - ff.decompileContext(); - } + output = new File(arg.substring(3)); + } else if (arg.startsWith("-l=")) { + if (lineMap != null) { + throw new RuntimeException("Unable to set more than one lineMap file."); + } + + lineMap = new File(arg.substring(3)); + } else if (arg.startsWith("-t=")) { + numThreads = Integer.parseInt(arg.substring(3)); + } else { + if (input != null) { + throw new RuntimeException("Unable to set more than one input."); + } + + input = new File(arg); + } + } + } + + Objects.requireNonNull(input, "Input not set."); + Objects.requireNonNull(output, "Output not set."); + + runFF(options, libraries, input, output, lineMap); + } + + public static void runFF(Map options, List libraries, File input, File output, File lineMap) { + IResultSaver saver = new ThreadSafeResultSaver(() -> output, () -> lineMap); + IFernflowerLogger logger = new ThreadIDFFLogger(); + Fernflower ff = new Fernflower(FernFlowerUtils::getBytecode, saver, options, logger); + + for (File library : libraries) { + ff.addLibrary(library); + } + + ff.addSource(input); + ff.decompileContext(); + } } diff --git a/src/main/java/net/fabricmc/loom/task/fernflower/NoopFFLogger.java b/src/main/java/net/fabricmc/loom/task/fernflower/NoopFFLogger.java index 83feb36..6e03a1c 100644 --- a/src/main/java/net/fabricmc/loom/task/fernflower/NoopFFLogger.java +++ b/src/main/java/net/fabricmc/loom/task/fernflower/NoopFFLogger.java @@ -31,14 +31,9 @@ import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; * Created by covers1624 on 11/02/19. */ public class NoopFFLogger extends IFernflowerLogger { + @Override + public void writeMessage(String message, Severity severity) { } - @Override - public void writeMessage(String message, Severity severity) { - - } - - @Override - public void writeMessage(String message, Severity severity, Throwable t) { - - } + @Override + public void writeMessage(String message, Severity severity, Throwable t) { } } diff --git a/src/main/java/net/fabricmc/loom/task/fernflower/ThreadIDFFLogger.java b/src/main/java/net/fabricmc/loom/task/fernflower/ThreadIDFFLogger.java index d10baaa..2740299 100644 --- a/src/main/java/net/fabricmc/loom/task/fernflower/ThreadIDFFLogger.java +++ b/src/main/java/net/fabricmc/loom/task/fernflower/ThreadIDFFLogger.java @@ -24,108 +24,108 @@ package net.fabricmc.loom.task.fernflower; -import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; - import java.io.PrintStream; import java.text.MessageFormat; import java.util.Stack; +import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; + /** * This logger simply prints what each thread is doing * to the console in a machine parsable way. * - * Created by covers1624 on 11/02/19. + *

Created by covers1624 on 11/02/19. */ public class ThreadIDFFLogger extends IFernflowerLogger { + public final PrintStream stdOut; + public final PrintStream stdErr; - public final PrintStream stdOut; - public final PrintStream stdErr; + private ThreadLocal> workingClass = ThreadLocal.withInitial(Stack::new); + private ThreadLocal> line = ThreadLocal.withInitial(Stack::new); - private ThreadLocal> workingClass = ThreadLocal.withInitial(Stack::new); - private ThreadLocal> line = ThreadLocal.withInitial(Stack::new); + public ThreadIDFFLogger() { + this(System.err, System.out); + } - public ThreadIDFFLogger() { - this(System.err, System.out); - } + public ThreadIDFFLogger(PrintStream stdOut, PrintStream stdErr) { + this.stdOut = stdOut; + this.stdErr = stdErr; + } - public ThreadIDFFLogger(PrintStream stdOut, PrintStream stdErr) { - this.stdOut = stdOut; - this.stdErr = stdErr; - } + @Override + public void writeMessage(String message, Severity severity) { + System.err.println(message); + } - @Override - public void writeMessage(String message, Severity severity) { - System.err.println(message); - } + @Override + public void writeMessage(String message, Severity severity, Throwable t) { + System.err.println(message); + t.printStackTrace(System.err); + } - @Override - public void writeMessage(String message, Severity severity, Throwable t) { - System.err.println(message); - t.printStackTrace(System.err); - } + private void print() { + Thread thread = Thread.currentThread(); + long id = thread.getId(); - private void print() { - Thread thread = Thread.currentThread(); - long id = thread.getId(); - if (line.get().isEmpty()) { - System.out.println(MessageFormat.format("{0} :: waiting", id)); - return; - } - String line = this.line.get().peek(); - System.out.println(MessageFormat.format("{0} :: {1}", id, line).trim()); - } + if (line.get().isEmpty()) { + System.out.println(MessageFormat.format("{0} :: waiting", id)); + return; + } - @Override - public void startReadingClass(String className) { - workingClass.get().push(className); - line.get().push("Decompiling " + className); - print(); - } + String line = this.line.get().peek(); + System.out.println(MessageFormat.format("{0} :: {1}", id, line).trim()); + } - @Override - public void startClass(String className) { - workingClass.get().push(className); - line.get().push("Decompiling " + className); - print(); - } + @Override + public void startReadingClass(String className) { + workingClass.get().push(className); + line.get().push("Decompiling " + className); + print(); + } - @Override - public void startMethod(String methodName) { - String className = workingClass.get().peek(); - line.get().push("Decompiling " + className + "." + methodName.substring(0, methodName.indexOf(" "))); - print(); - } + @Override + public void startClass(String className) { + workingClass.get().push(className); + line.get().push("Decompiling " + className); + print(); + } - @Override - public void endMethod() { - line.get().pop(); - print(); - } + @Override + public void startMethod(String methodName) { + String className = workingClass.get().peek(); + line.get().push("Decompiling " + className + "." + methodName.substring(0, methodName.indexOf(" "))); + print(); + } - @Override - public void endClass() { - line.get().pop(); - workingClass.get().pop(); - print(); - } + @Override + public void endMethod() { + line.get().pop(); + print(); + } - @Override - public void startWriteClass(String className) { - line.get().push("Writing " + className); - print(); - } + @Override + public void endClass() { + line.get().pop(); + workingClass.get().pop(); + print(); + } - @Override - public void endWriteClass() { - line.get().pop(); - print(); - } + @Override + public void startWriteClass(String className) { + line.get().push("Writing " + className); + print(); + } - @Override - public void endReadingClass() { - line.get().pop(); - workingClass.get().pop(); - print(); - } + @Override + public void endWriteClass() { + line.get().pop(); + print(); + } + @Override + public void endReadingClass() { + line.get().pop(); + workingClass.get().pop(); + print(); + } } diff --git a/src/main/java/net/fabricmc/loom/task/fernflower/ThreadSafeResultSaver.java b/src/main/java/net/fabricmc/loom/task/fernflower/ThreadSafeResultSaver.java index 46a81d1..87a8d21 100644 --- a/src/main/java/net/fabricmc/loom/task/fernflower/ThreadSafeResultSaver.java +++ b/src/main/java/net/fabricmc/loom/task/fernflower/ThreadSafeResultSaver.java @@ -24,11 +24,11 @@ package net.fabricmc.loom.task.fernflower; -import net.fabricmc.fernflower.api.IFabricResultSaver; -import org.jetbrains.java.decompiler.main.DecompilerContext; -import org.jetbrains.java.decompiler.main.extern.IResultSaver; - -import java.io.*; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; @@ -42,108 +42,136 @@ import java.util.jar.Manifest; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; +import org.jetbrains.java.decompiler.main.DecompilerContext; +import org.jetbrains.java.decompiler.main.extern.IResultSaver; + +import net.fabricmc.fernflower.api.IFabricResultSaver; + /** * Created by covers1624 on 18/02/19. */ public class ThreadSafeResultSaver implements IResultSaver, IFabricResultSaver { - private final Supplier output; - private final Supplier lineMapFile; + private final Supplier output; + private final Supplier lineMapFile; - public Map outputStreams = new HashMap<>(); - public Map saveExecutors = new HashMap<>(); - public PrintWriter lineMapWriter; + public Map outputStreams = new HashMap<>(); + public Map saveExecutors = new HashMap<>(); + public PrintWriter lineMapWriter; - public ThreadSafeResultSaver(Supplier output, Supplier lineMapFile) { - this.output = output; - this.lineMapFile = lineMapFile; - } + public ThreadSafeResultSaver(Supplier output, Supplier lineMapFile) { + this.output = output; + this.lineMapFile = lineMapFile; + } - @Override - public void createArchive(String path, String archiveName, Manifest manifest) { - String key = path + "/" + archiveName; - File file = output.get(); - try { - FileOutputStream fos = new FileOutputStream(file); - ZipOutputStream zos = manifest == null ? new ZipOutputStream(fos) : new JarOutputStream(fos, manifest); - outputStreams.put(key, zos); - saveExecutors.put(key, Executors.newSingleThreadExecutor()); - } catch (IOException e) { - throw new RuntimeException("Unable to create archive: " + file, e); - } - if (lineMapFile.get() != null) { - try { - lineMapWriter = new PrintWriter(new FileWriter(lineMapFile.get())); - } catch (IOException e) { - throw new RuntimeException("Unable to create line mapping file: " + lineMapFile.get(), e); - } - } - } + @Override + public void createArchive(String path, String archiveName, Manifest manifest) { + String key = path + "/" + archiveName; + File file = output.get(); - @Override - public void saveClassEntry(String path, String archiveName, String qualifiedName, String entryName, String content) { - this.saveClassEntry(path, archiveName, qualifiedName, entryName, content, null); - } + try { + FileOutputStream fos = new FileOutputStream(file); + ZipOutputStream zos = manifest == null ? new ZipOutputStream(fos) : new JarOutputStream(fos, manifest); + outputStreams.put(key, zos); + saveExecutors.put(key, Executors.newSingleThreadExecutor()); + } catch (IOException e) { + throw new RuntimeException("Unable to create archive: " + file, e); + } - @Override - public void saveClassEntry(String path, String archiveName, String qualifiedName, String entryName, String content, int[] mapping) { - String key = path + "/" + archiveName; - ExecutorService executor = saveExecutors.get(key); - executor.submit(() -> { - ZipOutputStream zos = outputStreams.get(key); - try { - zos.putNextEntry(new ZipEntry(entryName)); - if (content != null) { - zos.write(content.getBytes(StandardCharsets.UTF_8)); - } - } catch (IOException e) { - DecompilerContext.getLogger().writeMessage("Cannot write entry " + entryName, e); - } - if (mapping != null && lineMapWriter != null) { - int maxLine = 0; - int maxLineDest = 0; - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < mapping.length; i += 2) { - maxLine = Math.max(maxLine, mapping[i]); - maxLineDest = Math.max(maxLineDest, mapping[i + 1]); - builder.append("\t").append(mapping[i]).append("\t").append(mapping[i + 1]).append("\n"); - } - lineMapWriter.println(qualifiedName + "\t" + maxLine + "\t" + maxLineDest); - lineMapWriter.println(builder.toString()); - } - }); - } + if (lineMapFile.get() != null) { + try { + lineMapWriter = new PrintWriter(new FileWriter(lineMapFile.get())); + } catch (IOException e) { + throw new RuntimeException("Unable to create line mapping file: " + lineMapFile.get(), e); + } + } + } - @Override - public void closeArchive(String path, String archiveName) { - String key = path + "/" + archiveName; - ExecutorService executor = saveExecutors.get(key); - Future closeFuture = executor.submit(() -> { - ZipOutputStream zos = outputStreams.get(key); - try { - zos.close(); - } catch (IOException e) { - throw new RuntimeException("Unable to close zip. " + key, e); - } - }); - executor.shutdown(); - try { - closeFuture.get(); - } catch (InterruptedException | ExecutionException e) { - throw new RuntimeException(e); - } - outputStreams.remove(key); - saveExecutors.remove(key); - if (lineMapWriter != null) { - lineMapWriter.flush(); - lineMapWriter.close(); - } - } + @Override + public void saveClassEntry(String path, String archiveName, String qualifiedName, String entryName, String content) { + this.saveClassEntry(path, archiveName, qualifiedName, entryName, content, null); + } - //@formatter:off - @Override public void saveFolder(String path) { } - @Override public void copyFile(String source, String path, String entryName) { } - @Override public void saveClassFile(String path, String qualifiedName, String entryName, String content, int[] mapping) { } - @Override public void saveDirEntry(String path, String archiveName, String entryName) { } - @Override public void copyEntry(String source, String path, String archiveName, String entry) { } - //@formatter:on + @Override + public void saveClassEntry(String path, String archiveName, String qualifiedName, String entryName, String content, int[] mapping) { + String key = path + "/" + archiveName; + ExecutorService executor = saveExecutors.get(key); + executor.submit(() -> { + ZipOutputStream zos = outputStreams.get(key); + + try { + zos.putNextEntry(new ZipEntry(entryName)); + + if (content != null) { + zos.write(content.getBytes(StandardCharsets.UTF_8)); + } + } catch (IOException e) { + DecompilerContext.getLogger().writeMessage("Cannot write entry " + entryName, e); + } + + if (mapping != null && lineMapWriter != null) { + int maxLine = 0; + int maxLineDest = 0; + StringBuilder builder = new StringBuilder(); + + for (int i = 0; i < mapping.length; i += 2) { + maxLine = Math.max(maxLine, mapping[i]); + maxLineDest = Math.max(maxLineDest, mapping[i + 1]); + builder.append("\t").append(mapping[i]).append("\t").append(mapping[i + 1]).append("\n"); + } + + lineMapWriter.println(qualifiedName + "\t" + maxLine + "\t" + maxLineDest); + lineMapWriter.println(builder.toString()); + } + }); + } + + @Override + public void closeArchive(String path, String archiveName) { + String key = path + "/" + archiveName; + ExecutorService executor = saveExecutors.get(key); + Future closeFuture = executor.submit(() -> { + ZipOutputStream zos = outputStreams.get(key); + + try { + zos.close(); + } catch (IOException e) { + throw new RuntimeException("Unable to close zip. " + key, e); + } + }); + executor.shutdown(); + + try { + closeFuture.get(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + + outputStreams.remove(key); + saveExecutors.remove(key); + + if (lineMapWriter != null) { + lineMapWriter.flush(); + lineMapWriter.close(); + } + } + + @Override + public void saveFolder(String path) { + } + + @Override + public void copyFile(String source, String path, String entryName) { + } + + @Override + public void saveClassFile(String path, String qualifiedName, String entryName, String content, int[] mapping) { + } + + @Override + public void saveDirEntry(String path, String archiveName, String entryName) { + } + + @Override + public void copyEntry(String source, String path, String archiveName, String entry) { + } } diff --git a/src/main/java/net/fabricmc/loom/util/Checksum.java b/src/main/java/net/fabricmc/loom/util/Checksum.java index 5ad9d0c..ab6ab8e 100644 --- a/src/main/java/net/fabricmc/loom/util/Checksum.java +++ b/src/main/java/net/fabricmc/loom/util/Checksum.java @@ -24,15 +24,15 @@ package net.fabricmc.loom.util; +import java.io.File; +import java.io.IOException; + import com.google.common.hash.HashCode; import com.google.common.hash.Hashing; import com.google.common.io.Files; import org.gradle.api.logging.Logger; import org.gradle.api.logging.Logging; -import java.io.File; -import java.io.IOException; - public class Checksum { private static final Logger log = Logging.getLogger(Checksum.class); @@ -40,18 +40,22 @@ public class Checksum { if (file == null) { return false; } + try { //noinspection deprecation HashCode hash = Files.asByteSource(file).hash(Hashing.sha1()); StringBuilder builder = new StringBuilder(); + for (Byte hashBytes : hash.asBytes()) { builder.append(Integer.toString((hashBytes & 0xFF) + 0x100, 16).substring(1)); } + log.debug("Checksum check: '" + builder.toString() + "' == '" + checksum + "'?"); return builder.toString().equals(checksum); } catch (IOException e) { e.printStackTrace(); } + return false; } } diff --git a/src/main/java/net/fabricmc/loom/util/Constants.java b/src/main/java/net/fabricmc/loom/util/Constants.java index d75aec8..c2f0eab 100644 --- a/src/main/java/net/fabricmc/loom/util/Constants.java +++ b/src/main/java/net/fabricmc/loom/util/Constants.java @@ -24,13 +24,11 @@ package net.fabricmc.loom.util; +import java.util.List; import com.google.common.collect.ImmutableList; -import java.util.List; - public class Constants { - public static final String DEFAULT_FABRIC_CLIENT_TWEAKER = "net.fabricmc.loader.launch.FabricClientTweaker"; public static final String DEFAULT_FABRIC_SERVER_TWEAKER = "net.fabricmc.loader.launch.FabricServerTweaker"; @@ -41,13 +39,9 @@ public class Constants { public static final String MOD_COMPILE_CLASSPATH = "modCompileClasspath"; public static final String MOD_COMPILE_CLASSPATH_MAPPED = "modCompileClasspathMapped"; - public static final List MOD_COMPILE_ENTRIES = ImmutableList.of( - new RemappedConfigurationEntry("modCompile", "compile", true, "compile"), - new RemappedConfigurationEntry("modApi", "api", true, "compile"), - new RemappedConfigurationEntry("modImplementation", "implementation", true, "runtime"), - new RemappedConfigurationEntry("modRuntime", "runtimeOnly", false, ""), - new RemappedConfigurationEntry("modCompileOnly", "compileOnly", true, "") - ); + public static final List MOD_COMPILE_ENTRIES = ImmutableList.of(new RemappedConfigurationEntry("modCompile", "compile", true, "compile"), new RemappedConfigurationEntry("modApi", "api", true, "compile"), + new RemappedConfigurationEntry("modImplementation", "implementation", true, "runtime"), new RemappedConfigurationEntry("modRuntime", "runtimeOnly", false, ""), + new RemappedConfigurationEntry("modCompileOnly", "compileOnly", true, "")); public static final String INCLUDE = "include"; public static final String MINECRAFT = "minecraft"; diff --git a/src/main/java/net/fabricmc/loom/util/ConsumingOutputStream.java b/src/main/java/net/fabricmc/loom/util/ConsumingOutputStream.java index 524da83..fdb0abd 100644 --- a/src/main/java/net/fabricmc/loom/util/ConsumingOutputStream.java +++ b/src/main/java/net/fabricmc/loom/util/ConsumingOutputStream.java @@ -32,33 +32,36 @@ import java.util.function.Consumer; * Created by covers1624 on 20/12/18. */ public class ConsumingOutputStream extends OutputStream { + private final Consumer consumer; - private final Consumer consumer; + private StringBuilder buffer = new StringBuilder(); - private StringBuilder buffer = new StringBuilder(); + public ConsumingOutputStream(Consumer consumer) { + this.consumer = consumer; + } - public ConsumingOutputStream(Consumer consumer) { - this.consumer = consumer; - } + @Override + public void write(int b) throws IOException { + char ch = (char) (b & 0xFF); + buffer.append(ch); - @Override - public void write(int b) throws IOException { - char ch = (char) (b & 0xFF); - buffer.append(ch); - if (ch == '\n' || ch == '\r') { - flush(); - } - } + if (ch == '\n' || ch == '\r') { + flush(); + } + } - @Override - public void flush() throws IOException { - String str = buffer.toString(); - if (str.endsWith("\r") || str.endsWith("\n")) { - str = str.trim(); - if (!str.isEmpty()) { - consumer.accept(str); - } - buffer = new StringBuilder(); - } - } + @Override + public void flush() throws IOException { + String str = buffer.toString(); + + if (str.endsWith("\r") || str.endsWith("\n")) { + str = str.trim(); + + if (!str.isEmpty()) { + consumer.accept(str); + } + + buffer = new StringBuilder(); + } + } } diff --git a/src/main/java/net/fabricmc/loom/util/DependencyProvider.java b/src/main/java/net/fabricmc/loom/util/DependencyProvider.java index a82734e..25bc1de 100644 --- a/src/main/java/net/fabricmc/loom/util/DependencyProvider.java +++ b/src/main/java/net/fabricmc/loom/util/DependencyProvider.java @@ -24,33 +24,8 @@ package net.fabricmc.loom.util; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import com.google.gson.Gson; -import com.google.gson.JsonObject; - -import net.fabricmc.loom.LoomGradleExtension; - -import org.apache.commons.io.FilenameUtils; -import org.gradle.api.InvalidUserDataException; -import org.gradle.api.Project; -import org.gradle.api.artifacts.Configuration; -import org.gradle.api.artifacts.Dependency; -import org.gradle.api.artifacts.ResolvedArtifact; -import org.gradle.api.artifacts.ResolvedDependency; -import org.gradle.api.artifacts.SelfResolvingDependency; -import org.gradle.api.artifacts.query.ArtifactResolutionQuery; -import org.gradle.api.artifacts.result.ArtifactResult; -import org.gradle.api.artifacts.result.ComponentArtifactsResult; -import org.gradle.api.artifacts.result.ResolvedArtifactResult; -import org.gradle.internal.component.external.model.DefaultModuleComponentIdentifier; -import org.gradle.jvm.JvmLibrary; -import org.gradle.language.base.artifact.SourcesArtifact; -import org.zeroturnaround.zip.ZipUtil; - import java.io.File; import java.nio.charset.StandardCharsets; -import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; @@ -60,8 +35,21 @@ import java.util.Set; import java.util.function.Consumer; import java.util.stream.Collectors; -public abstract class DependencyProvider { +import com.google.common.collect.Iterables; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import org.apache.commons.io.FilenameUtils; +import org.zeroturnaround.zip.ZipUtil; +import org.gradle.api.InvalidUserDataException; +import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.artifacts.Dependency; +import org.gradle.api.artifacts.ResolvedDependency; +import org.gradle.api.artifacts.SelfResolvingDependency; +import net.fabricmc.loom.LoomGradleExtension; + +public abstract class DependencyProvider { private LoomDependencyManager dependencyManager; public abstract void provide(DependencyInfo dependency, Project project, LoomGradleExtension extension, Consumer postPopulationScheduler) throws Exception; @@ -73,13 +61,14 @@ public abstract class DependencyProvider { } public void addDependency(Object object, Project project, String target) { - if(object instanceof File){ + if (object instanceof File) { object = project.files(object); } + project.getDependencies().add(target, object); } - public void register(LoomDependencyManager dependencyManager){ + public void register(LoomDependencyManager dependencyManager) { this.dependencyManager = dependencyManager; } @@ -132,14 +121,17 @@ public abstract class DependencyProvider { public Optional resolveFile() { Set files = resolve(); + if (files.isEmpty()) { return Optional.empty(); } else if (files.size() > 1) { StringBuilder builder = new StringBuilder(this.toString()); builder.append(" resolves to more than one file:"); + for (File f : files) { builder.append("\n\t-").append(f.getAbsolutePath()); } + throw new RuntimeException(builder.toString()); } else { return files.stream().findFirst(); @@ -151,11 +143,11 @@ public abstract class DependencyProvider { return getDepString(); } - public String getDepString(){ + public String getDepString() { return dependency.getGroup() + ":" + dependency.getName() + ":" + dependency.getVersion(); } - public String getResolvedDepString(){ + public String getResolvedDepString() { return dependency.getGroup() + ":" + dependency.getName() + ":" + getResolvedVersion(); } } @@ -178,7 +170,6 @@ public abstract class DependencyProvider { default: //File collection, try work out the classifiers List sortedFiles = files.stream().sorted(Comparator.comparing(File::getName, Comparator.comparingInt(String::length))).collect(Collectors.toList()); - //First element in sortedFiles is the one with the shortest name, we presume all the others are different classifier types of this File shortest = sortedFiles.remove(0); String shortestName = FilenameUtils.removeExtension(shortest.getName()); //name.jar -> name @@ -192,8 +183,8 @@ public abstract class DependencyProvider { //We appear to be right, therefore this is the normal dependency file we want classifierToFile.put("", shortest); - int start = shortestName.length(); + for (File file : sortedFiles) { //Now we just have to work out what classifier type the other files are, this shouldn't even return an empty string String classifier = FilenameUtils.removeExtension(file.getName()).substring(start); @@ -206,16 +197,21 @@ public abstract class DependencyProvider { } File root = classifierToFile.get(""); //We've built the classifierToFile map, now to try find a name and version for our dependency + if ("jar".equals(FilenameUtils.getExtension(root.getName())) && ZipUtil.containsEntry(root, "fabric.mod.json")) { //It's a Fabric mod, see how much we can extract out JsonObject json = new Gson().fromJson(new String(ZipUtil.unpackEntry(root, "fabric.mod.json"), StandardCharsets.UTF_8), JsonObject.class); - if (json == null || !json.has("id") || !json.has("version")) throw new IllegalArgumentException("Invalid Fabric mod jar: " + root + " (malformed json: " + json + ')'); - if (json.has("name")) {//Go for the name field if it's got one + if (json == null || !json.has("id") || !json.has("version")) { + throw new IllegalArgumentException("Invalid Fabric mod jar: " + root + " (malformed json: " + json + ')'); + } + + if (json.has("name")) { //Go for the name field if it's got one name = json.get("name").getAsString(); } else { name = json.get("id").getAsString(); } + version = json.get("version").getAsString(); } else { //Not a Fabric mod, just have to make something up diff --git a/src/main/java/net/fabricmc/loom/util/DownloadUtil.java b/src/main/java/net/fabricmc/loom/util/DownloadUtil.java index 9d06730..44dcb60 100644 --- a/src/main/java/net/fabricmc/loom/util/DownloadUtil.java +++ b/src/main/java/net/fabricmc/loom/util/DownloadUtil.java @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ + package net.fabricmc.loom.util; import java.io.File; @@ -29,21 +30,18 @@ import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; +import com.google.common.io.Files; import org.apache.commons.io.FileUtils; - import org.gradle.api.Project; import org.gradle.api.logging.Logger; -import com.google.common.io.Files; - public class DownloadUtil { /** - * Download from the given {@link URL} to the given {@link File} so long as there are differences between them + * Download from the given {@link URL} to the given {@link File} so long as there are differences between them. * * @param from The URL of the file to be downloaded * @param to The destination to be saved to, and compared against if it exists * @param logger The logger to print everything to, typically from {@link Project#getLogger()} - * * @throws IOException If an exception occurs during the process */ public static void downloadIfChanged(URL from, File to, Logger logger) throws IOException { @@ -51,24 +49,28 @@ public class DownloadUtil { } /** - * Download from the given {@link URL} to the given {@link File} so long as there are differences between them + * Download from the given {@link URL} to the given {@link File} so long as there are differences between them. * * @param from The URL of the file to be downloaded * @param to The destination to be saved to, and compared against if it exists * @param logger The logger to print information to, typically from {@link Project#getLogger()} * @param quiet Whether to only print warnings (when true) or everything - * * @throws IOException If an exception occurs during the process */ public static void downloadIfChanged(URL from, File to, Logger logger, boolean quiet) throws IOException { HttpURLConnection connection = (HttpURLConnection) from.openConnection(); //If the output already exists we'll use it's last modified time - if (to.exists()) connection.setIfModifiedSince(to.lastModified()); + if (to.exists()) { + connection.setIfModifiedSince(to.lastModified()); + } //Try use the ETag if there's one for the file we're downloading String etag = loadETag(to, logger); - if (etag != null) connection.setRequestProperty("If-None-Match", etag); + + if (etag != null) { + connection.setRequestProperty("If-None-Match", etag); + } //We want to download gzip compressed stuff connection.setRequestProperty("Accept-Encoding", "gzip"); @@ -80,21 +82,29 @@ public class DownloadUtil { connection.connect(); int code = connection.getResponseCode(); + if ((code < 200 || code > 299) && code != HttpURLConnection.HTTP_NOT_MODIFIED) { //Didn't get what we expected throw new IOException(connection.getResponseMessage()); } long modifyTime = connection.getHeaderFieldDate("Last-Modified", -1); + if (to.exists() && (code == HttpURLConnection.HTTP_NOT_MODIFIED || modifyTime > 0 && to.lastModified() >= modifyTime)) { - if (!quiet) logger.info("'{}' Not Modified, skipping.", to); + if (!quiet) { + logger.info("'{}' Not Modified, skipping.", to); + } + return; //What we've got is already fine } long contentLength = connection.getContentLengthLong(); - if (!quiet && contentLength >= 0) logger.info("'{}' Changed, downloading {}", to, toNiceSize(contentLength)); - try {//Try download to the output + if (!quiet && contentLength >= 0) { + logger.info("'{}' Changed, downloading {}", to, toNiceSize(contentLength)); + } + + try { //Try download to the output FileUtils.copyInputStreamToFile(connection.getInputStream(), to); } catch (IOException e) { to.delete(); //Probably isn't good if it fails to copy/save @@ -102,23 +112,27 @@ public class DownloadUtil { } //Set the modify time to match the server's (if we know it) - if (modifyTime > 0) to.setLastModified(modifyTime); + if (modifyTime > 0) { + to.setLastModified(modifyTime); + } //Save the ETag (if we know it) String eTag = connection.getHeaderField("ETag"); + if (eTag != null) { //Log if we get a weak ETag and we're not on quiet - if (!quiet && eTag.startsWith("W/")) logger.warn("Weak ETag found."); + if (!quiet && eTag.startsWith("W/")) { + logger.warn("Weak ETag found."); + } saveETag(to, eTag, logger); } } /** - * Creates a new file in the same directory as the given file with .etag on the end of the name + * Creates a new file in the same directory as the given file with .etag on the end of the name. * * @param file The file to produce the ETag for - * * @return The (uncreated) ETag file for the given file */ private static File getETagFile(File file) { @@ -126,16 +140,18 @@ public class DownloadUtil { } /** - * Attempt to load an ETag for the given file, if it exists + * Attempt to load an ETag for the given file, if it exists. * * @param to The file to load an ETag for * @param logger The logger to print errors to if it goes wrong - * * @return The ETag for the given file, or null if it doesn't exist */ private static String loadETag(File to, Logger logger) { File eTagFile = getETagFile(to); - if (!eTagFile.exists()) return null; + + if (!eTagFile.exists()) { + return null; + } try { return Files.asCharSource(eTagFile, StandardCharsets.UTF_8).read(); @@ -146,7 +162,7 @@ public class DownloadUtil { } /** - * Saves the given ETag for the given file, replacing it if it already exists + * Saves the given ETag for the given file, replacing it if it already exists. * * @param to The file to save the ETag for * @param eTag The ETag to be saved @@ -154,8 +170,12 @@ public class DownloadUtil { */ private static void saveETag(File to, String eTag, Logger logger) { File eTagFile = getETagFile(to); + try { - if (!eTagFile.exists()) eTagFile.createNewFile(); + if (!eTagFile.exists()) { + eTagFile.createNewFile(); + } + Files.asCharSink(eTagFile, StandardCharsets.UTF_8).write(eTag); } catch (IOException e) { logger.warn("Error saving ETag file '{}'.", eTagFile, e); @@ -163,10 +183,9 @@ public class DownloadUtil { } /** - * Format the given number of bytes as a more human readable string + * Format the given number of bytes as a more human readable string. * * @param bytes The number of bytes - * * @return The given number of bytes formatted to kilobytes, megabytes or gigabytes if appropriate */ private static String toNiceSize(long bytes) { @@ -192,8 +211,9 @@ public class DownloadUtil { } File etagFile = getETagFile(file); + if (etagFile.exists()) { etagFile.delete(); } } -} \ No newline at end of file +} diff --git a/src/main/java/net/fabricmc/loom/util/GradleSupport.java b/src/main/java/net/fabricmc/loom/util/GradleSupport.java index 92c9a63..f205209 100644 --- a/src/main/java/net/fabricmc/loom/util/GradleSupport.java +++ b/src/main/java/net/fabricmc/loom/util/GradleSupport.java @@ -24,23 +24,23 @@ package net.fabricmc.loom.util; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + import org.gradle.api.Project; import org.gradle.api.file.RegularFileProperty; import org.gradle.api.model.ObjectFactory; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - //This is used to bridge the gap over large gradle api changes. public class GradleSupport { - - public static RegularFileProperty getfileProperty(Project project){ + public static RegularFileProperty getfileProperty(Project project) { try { //First try the new method, if that fails fall back. return getfilePropertyModern(project); - } catch (Exception e){ + } catch (Exception e) { //Nope } + return getfilePropertyLegacy(project); } @@ -51,7 +51,7 @@ public class GradleSupport { return (RegularFileProperty) method.invoke(objectFactory); } - private static RegularFileProperty getfilePropertyLegacy(Project project){ + private static RegularFileProperty getfilePropertyLegacy(Project project) { return project.getLayout().fileProperty(); } } diff --git a/src/main/java/net/fabricmc/loom/util/GroovyXmlUtil.java b/src/main/java/net/fabricmc/loom/util/GroovyXmlUtil.java index 42f5e37..fe651e3 100644 --- a/src/main/java/net/fabricmc/loom/util/GroovyXmlUtil.java +++ b/src/main/java/net/fabricmc/loom/util/GroovyXmlUtil.java @@ -24,17 +24,15 @@ package net.fabricmc.loom.util; -import groovy.util.Node; - import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; -public final class GroovyXmlUtil { - private GroovyXmlUtil() { +import groovy.util.Node; - } +public final class GroovyXmlUtil { + private GroovyXmlUtil() { } public static Node getOrCreateNode(Node parent, String name) { for (Object object : parent.children()) { diff --git a/src/main/java/net/fabricmc/loom/util/LineNumberRemapper.java b/src/main/java/net/fabricmc/loom/util/LineNumberRemapper.java index 5c3d261..4e7d956 100644 --- a/src/main/java/net/fabricmc/loom/util/LineNumberRemapper.java +++ b/src/main/java/net/fabricmc/loom/util/LineNumberRemapper.java @@ -24,138 +24,160 @@ package net.fabricmc.loom.util; -import net.fabricmc.loom.util.progress.ProgressLogger; -import org.gradle.api.logging.Logger; -import org.objectweb.asm.*; +import static java.text.MessageFormat.format; -import java.io.*; -import java.nio.file.*; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributes; import java.util.HashMap; import java.util.Map; -import static java.text.MessageFormat.format; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +import net.fabricmc.loom.util.progress.ProgressLogger; /** * TODO, Move to stitch. * Created by covers1624 on 18/02/19. */ public class LineNumberRemapper { + private final Map lineMap = new HashMap<>(); - private final Map lineMap = new HashMap<>(); + public void readMappings(File lineMappings) { + try (BufferedReader reader = new BufferedReader(new FileReader(lineMappings))) { + RClass clazz = null; + String line = null; + int i = 0; - public void readMappings(File lineMappings) { - try (BufferedReader reader = new BufferedReader(new FileReader(lineMappings))) { - RClass clazz = null; - String line = null; - int i = 0; - try { - while ((line = reader.readLine()) != null) { - if (line.isEmpty()) { - continue; - } - String[] segs = line.trim().split("\t"); - if (line.charAt(0) != '\t') { - clazz = lineMap.computeIfAbsent(segs[0], RClass::new); - clazz.maxLine = Integer.parseInt(segs[1]); - clazz.maxLineDest = Integer.parseInt(segs[2]); - } else { - clazz.lineMap.put(Integer.parseInt(segs[0]), Integer.parseInt(segs[1])); - } - i++; - } - } catch (Exception e) { - throw new RuntimeException(format("Exception reading mapping line @{0}: {1}", i, line), e); - } - } catch (IOException e) { - throw new RuntimeException("Exception reading LineMappings file.", e); - } - } + try { + while ((line = reader.readLine()) != null) { + if (line.isEmpty()) { + continue; + } - public void process(ProgressLogger logger, Path input, Path output) throws IOException { - Files.walkFileTree(input, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - String rel = input.relativize(file).toString(); - Path dst = output.resolve(rel); - Path parent = dst.getParent(); - if (parent != null) { - Files.createDirectories(parent); - } - String fName = file.getFileName().toString(); - if (fName.endsWith(".class")) { - if (Files.exists(dst)) { - Files.delete(dst); - } - String idx = rel.substring(0, rel.length() - 6); - if (logger != null) { - logger.progress("Remapping " + idx); - } + String[] segs = line.trim().split("\t"); - int dollarPos = idx.indexOf('$'); //This makes the assumption that only Java classes are to be remapped. - if (dollarPos >= 0) { - idx = idx.substring(0, dollarPos); - } - if (lineMap.containsKey(idx)) { - try (InputStream is = Files.newInputStream(file)) { - ClassReader reader = new ClassReader(is); - ClassWriter writer = new ClassWriter(0); + if (line.charAt(0) != '\t') { + clazz = lineMap.computeIfAbsent(segs[0], RClass::new); + clazz.maxLine = Integer.parseInt(segs[1]); + clazz.maxLineDest = Integer.parseInt(segs[2]); + } else { + clazz.lineMap.put(Integer.parseInt(segs[0]), Integer.parseInt(segs[1])); + } - reader.accept(new LineNumberVisitor(Opcodes.ASM7, writer, lineMap.get(idx)), 0); - Files.write(dst, writer.toByteArray()); - } - } + i++; + } + } catch (Exception e) { + throw new RuntimeException(format("Exception reading mapping line @{0}: {1}", i, line), e); + } + } catch (IOException e) { + throw new RuntimeException("Exception reading LineMappings file.", e); + } + } - } else { - Files.copy(file, dst, StandardCopyOption.REPLACE_EXISTING); - } + public void process(ProgressLogger logger, Path input, Path output) throws IOException { + Files.walkFileTree(input, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + String rel = input.relativize(file).toString(); + Path dst = output.resolve(rel); + Path parent = dst.getParent(); - return FileVisitResult.CONTINUE; - } - }); - } + if (parent != null) { + Files.createDirectories(parent); + } - private static class LineNumberVisitor extends ClassVisitor { + String fName = file.getFileName().toString(); - private final RClass rClass; + if (fName.endsWith(".class")) { + if (Files.exists(dst)) { + Files.delete(dst); + } - public LineNumberVisitor(int api, ClassVisitor classVisitor, RClass rClass) { - super(api, classVisitor); - this.rClass = rClass; - } + String idx = rel.substring(0, rel.length() - 6); - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - return new MethodVisitor(api, super.visitMethod(access, name, descriptor, signature, exceptions)) { - @Override - public void visitLineNumber(int line, Label start) { - int tLine = line; - if (tLine <= 0) { - super.visitLineNumber(line, start); - } else if (tLine >= rClass.maxLine) { - super.visitLineNumber(rClass.maxLineDest, start); - } else { - Integer matchedLine = null; - while (tLine <= rClass.maxLine && ((matchedLine = rClass.lineMap.get(tLine)) == null)) { - tLine++; - } - super.visitLineNumber(matchedLine != null ? matchedLine : rClass.maxLineDest, start); - } - } - }; - } - } + if (logger != null) { + logger.progress("Remapping " + idx); + } - private static class RClass { + int dollarPos = idx.indexOf('$'); //This makes the assumption that only Java classes are to be remapped. - private final String name; - private int maxLine; - private int maxLineDest; - private Map lineMap = new HashMap<>(); + if (dollarPos >= 0) { + idx = idx.substring(0, dollarPos); + } - private RClass(String name) { - this.name = name; - } - } + if (lineMap.containsKey(idx)) { + try (InputStream is = Files.newInputStream(file)) { + ClassReader reader = new ClassReader(is); + ClassWriter writer = new ClassWriter(0); + reader.accept(new LineNumberVisitor(Opcodes.ASM7, writer, lineMap.get(idx)), 0); + Files.write(dst, writer.toByteArray()); + } + } + } else { + Files.copy(file, dst, StandardCopyOption.REPLACE_EXISTING); + } + + return FileVisitResult.CONTINUE; + } + }); + } + + private static class LineNumberVisitor extends ClassVisitor { + private final RClass rClass; + + LineNumberVisitor(int api, ClassVisitor classVisitor, RClass rClass) { + super(api, classVisitor); + this.rClass = rClass; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { + return new MethodVisitor(api, super.visitMethod(access, name, descriptor, signature, exceptions)) { + @Override + public void visitLineNumber(int line, Label start) { + int tLine = line; + + if (tLine <= 0) { + super.visitLineNumber(line, start); + } else if (tLine >= rClass.maxLine) { + super.visitLineNumber(rClass.maxLineDest, start); + } else { + Integer matchedLine = null; + + while (tLine <= rClass.maxLine && ((matchedLine = rClass.lineMap.get(tLine)) == null)) { + tLine++; + } + + super.visitLineNumber(matchedLine != null ? matchedLine : rClass.maxLineDest, start); + } + } + }; + } + } + + private static class RClass { + private final String name; + private int maxLine; + private int maxLineDest; + private Map lineMap = new HashMap<>(); + + private RClass(String name) { + this.name = name; + } + } } diff --git a/src/main/java/net/fabricmc/loom/util/LoomDependencyManager.java b/src/main/java/net/fabricmc/loom/util/LoomDependencyManager.java index 6be8fee..75742c7 100644 --- a/src/main/java/net/fabricmc/loom/util/LoomDependencyManager.java +++ b/src/main/java/net/fabricmc/loom/util/LoomDependencyManager.java @@ -24,19 +24,24 @@ package net.fabricmc.loom.util; -import com.google.gson.JsonObject; -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.providers.MappingsProvider; -import net.fabricmc.loom.util.DependencyProvider.DependencyInfo; +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import com.google.gson.JsonObject; import org.gradle.api.Project; import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.Dependency; import org.gradle.api.artifacts.ExternalModuleDependency; import org.gradle.api.artifacts.repositories.MavenArtifactRepository; -import java.io.File; -import java.util.*; +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.providers.MappingsProvider; +import net.fabricmc.loom.util.DependencyProvider.DependencyInfo; public class LoomDependencyManager { private static class ProviderList { @@ -50,27 +55,30 @@ public class LoomDependencyManager { private List dependencyProviderList = new ArrayList<>(); - public void addProvider(DependencyProvider provider){ - if(dependencyProviderList.contains(provider)){ + public void addProvider(DependencyProvider provider) { + if (dependencyProviderList.contains(provider)) { throw new RuntimeException("Provider is already registered"); } - if(getProvider(provider.getClass()) != null){ + + if (getProvider(provider.getClass()) != null) { throw new RuntimeException("Provider of this type is already registered"); } + provider.register(this); dependencyProviderList.add(provider); } - public T getProvider(Class clazz){ - for(DependencyProvider provider : dependencyProviderList){ - if(provider.getClass() == clazz){ + public T getProvider(Class clazz) { + for (DependencyProvider provider : dependencyProviderList) { + if (provider.getClass() == clazz) { return (T) provider; } } + return null; } - public void handleDependencies(Project project){ + public void handleDependencies(Project project) { List afterTasks = new ArrayList<>(); MappingsProvider mappingsProvider = null; @@ -80,7 +88,7 @@ public class LoomDependencyManager { Map providerListMap = new HashMap<>(); List targetProviders = new ArrayList<>(); - for(DependencyProvider provider : dependencyProviderList){ + for (DependencyProvider provider : dependencyProviderList) { providerListMap.computeIfAbsent(provider.getTargetConfig(), (k) -> { ProviderList list = new ProviderList(k); targetProviders.add(list); @@ -101,6 +109,7 @@ public class LoomDependencyManager { configuration.getDependencies().forEach(dependency -> { for (DependencyProvider provider : list.providers) { DependencyProvider.DependencyInfo info = DependencyInfo.create(project, dependency, configuration); + try { provider.provide(info, project, extension, afterTasks::add); } catch (Exception e) { @@ -114,13 +123,7 @@ public class LoomDependencyManager { String mappingsKey = mappingsProvider.mappingsName + "." + mappingsProvider.minecraftVersion.replace(' ', '_').replace('.', '_').replace('-', '_') + "." + mappingsProvider.mappingsVersion; for (RemappedConfigurationEntry entry : Constants.MOD_COMPILE_ENTRIES) { - ModCompileRemapper.remapDependencies( - project, mappingsKey, extension, - project.getConfigurations().getByName(entry.getSourceConfiguration()), - project.getConfigurations().getByName(entry.getRemappedConfiguration()), - project.getConfigurations().getByName(entry.getTargetConfiguration(project.getConfigurations())), - afterTasks::add - ); + ModCompileRemapper.remapDependencies(project, mappingsKey, extension, project.getConfigurations().getByName(entry.getSourceConfiguration()), project.getConfigurations().getByName(entry.getRemappedConfiguration()), project.getConfigurations().getByName(entry.getTargetConfiguration(project.getConfigurations())), afterTasks::add); } } @@ -133,9 +136,11 @@ public class LoomDependencyManager { for (Dependency dependency : configuration.getDependencies()) { DependencyInfo info = DependencyInfo.create(project, dependency, configuration); + for (File input : info.resolve()) { if (seenFiles.add(input)) { ModProcessor.readInstallerJson(input, project); + if (extension.getInstallerJson() != null) { project.getLogger().info("Found installer JSON in " + info); break; //Found it, probably don't need to look any further @@ -156,7 +161,7 @@ public class LoomDependencyManager { } } - private static void handleInstallerJson(JsonObject jsonObject, Project project){ + private static void handleInstallerJson(JsonObject jsonObject, Project project) { JsonObject libraries = jsonObject.get("libraries").getAsJsonObject(); Configuration mcDepsConfig = project.getConfigurations().getByName(Constants.MINECRAFT_DEPENDENCIES); Configuration apDepsConfig = project.getConfigurations().getByName("annotationProcessor"); @@ -171,16 +176,15 @@ public class LoomDependencyManager { project.getLogger().debug("Loom adding " + name + " from installer JSON"); - if(jsonElement.getAsJsonObject().has("url")){ + if (jsonElement.getAsJsonObject().has("url")) { String url = jsonElement.getAsJsonObject().get("url").getAsString(); - long count = project.getRepositories().stream() - .filter(artifactRepository -> artifactRepository instanceof MavenArtifactRepository) + long count = project.getRepositories().stream().filter(artifactRepository -> artifactRepository instanceof MavenArtifactRepository) .map(artifactRepository -> (MavenArtifactRepository) artifactRepository) .filter(mavenArtifactRepository -> mavenArtifactRepository.getUrl().toString().equalsIgnoreCase(url)).count(); - if(count == 0){ + + if (count == 0) { project.getRepositories().maven(mavenArtifactRepository -> mavenArtifactRepository.setUrl(jsonElement.getAsJsonObject().get("url").getAsString())); } - } }); } diff --git a/src/main/java/net/fabricmc/loom/util/MapJarsTiny.java b/src/main/java/net/fabricmc/loom/util/MapJarsTiny.java index d33e406..2f23e6f 100644 --- a/src/main/java/net/fabricmc/loom/util/MapJarsTiny.java +++ b/src/main/java/net/fabricmc/loom/util/MapJarsTiny.java @@ -24,32 +24,28 @@ package net.fabricmc.loom.util; - -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.providers.MinecraftMappedProvider; -import net.fabricmc.loom.providers.MinecraftProvider; -import net.fabricmc.loom.providers.MappingsProvider; -import net.fabricmc.tinyremapper.OutputConsumerPath; -import net.fabricmc.tinyremapper.TinyRemapper; -import net.fabricmc.tinyremapper.TinyUtils; -import org.gradle.api.Project; - import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.util.Arrays; -public class MapJarsTiny { +import org.gradle.api.Project; +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.providers.MappingsProvider; +import net.fabricmc.loom.providers.MinecraftMappedProvider; +import net.fabricmc.loom.providers.MinecraftProvider; +import net.fabricmc.tinyremapper.OutputConsumerPath; +import net.fabricmc.tinyremapper.TinyRemapper; + +public class MapJarsTiny { public void mapJars(MinecraftProvider jarProvider, MinecraftMappedProvider mapProvider, Project project) throws IOException { String fromM = "official"; LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); MappingsProvider mappingsProvider = extension.getMappingsProvider(); - Path[] classpath = mapProvider.getMapperPaths().stream() - .map(File::toPath) - .toArray(Path[]::new); + Path[] classpath = mapProvider.getMapperPaths().stream().map(File::toPath).toArray(Path[]::new); Path input = jarProvider.getMergedJar().toPath(); Path outputMapped = mapProvider.getMappedJar().toPath(); @@ -60,11 +56,7 @@ 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)).renameInvalidLocals(true).rebuildSourceFilenames(true).build(); try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(output).build()) { outputConsumer.addNonClassFiles(input); diff --git a/src/main/java/net/fabricmc/loom/util/MinecraftVersionInfo.java b/src/main/java/net/fabricmc/loom/util/MinecraftVersionInfo.java index 8ea9be5..c336410 100644 --- a/src/main/java/net/fabricmc/loom/util/MinecraftVersionInfo.java +++ b/src/main/java/net/fabricmc/loom/util/MinecraftVersionInfo.java @@ -24,15 +24,13 @@ package net.fabricmc.loom.util; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.providers.MinecraftLibraryProvider; - import java.io.File; import java.util.List; import java.util.Map; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + public class MinecraftVersionInfo { public List libraries; public Map downloads; @@ -93,14 +91,16 @@ public class MinecraftVersionInfo { return ""; } else { JsonElement element = natives.get(OperatingSystem.getOS().replace("${arch}", OperatingSystem.getArch())); - if(element == null){ + + if (element == null) { return ""; } + return "-" + element.getAsString().replace("\"", ""); } } - public boolean isNative(){ + public boolean isNative() { return getClassifier().contains("natives"); } @@ -110,6 +110,7 @@ public class MinecraftVersionInfo { } boolean success = false; + for (Rule rule : this.rules) { if (rule.os != null && rule.os.name != null) { if (rule.os.name.equalsIgnoreCase(OperatingSystem.getOS())) { @@ -119,6 +120,7 @@ public class MinecraftVersionInfo { success = rule.action.equalsIgnoreCase("allow"); } } + return success; } @@ -126,9 +128,11 @@ public class MinecraftVersionInfo { if (artifact == null) { artifact = new Artifact(name); } - if(natives != null){ + + if (natives != null) { JsonElement jsonElement = natives.get(OperatingSystem.getOS()); - if(jsonElement != null){ + + if (jsonElement != null) { return artifact.getArtifact(jsonElement.getAsString()); } } @@ -139,15 +143,17 @@ public class MinecraftVersionInfo { private class Artifact { private final String domain, name, version, classifier, ext; - public Artifact(String name) { + Artifact(String name) { String[] splitedArtifact = name.split(":"); int idx = splitedArtifact[splitedArtifact.length - 1].indexOf('@'); + if (idx != -1) { ext = splitedArtifact[splitedArtifact.length - 1].substring(idx + 1); splitedArtifact[splitedArtifact.length - 1] = splitedArtifact[splitedArtifact.length - 1].substring(0, idx); } else { ext = "jar"; } + this.domain = splitedArtifact[0]; this.name = splitedArtifact[1]; this.version = splitedArtifact[2]; @@ -156,15 +162,19 @@ public class MinecraftVersionInfo { public String getArtifact(String classifier) { String ret = domain + ":" + name + ":" + version; + if (classifier != null && classifier.indexOf('$') > -1) { classifier = classifier.replace("${arch}", Constants.SYSTEM_ARCH); } + if (classifier != null) { ret += ":" + classifier; } + if (!"jar".equals(ext)) { ret += "@" + ext; } + return ret; } diff --git a/src/main/java/net/fabricmc/loom/util/MixinRefmapHelper.java b/src/main/java/net/fabricmc/loom/util/MixinRefmapHelper.java index c644ab9..cb43110 100644 --- a/src/main/java/net/fabricmc/loom/util/MixinRefmapHelper.java +++ b/src/main/java/net/fabricmc/loom/util/MixinRefmapHelper.java @@ -24,15 +24,6 @@ package net.fabricmc.loom.util; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonObject; -import net.fabricmc.tinyremapper.TinyRemapper; -import org.objectweb.asm.commons.Remapper; -import org.zeroturnaround.zip.ZipUtil; -import org.zeroturnaround.zip.transform.StringZipEntryTransformer; -import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry; - import java.io.File; import java.io.IOException; import java.io.InputStreamReader; @@ -41,86 +32,91 @@ import java.util.HashSet; import java.util.Set; import java.util.zip.ZipEntry; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import org.zeroturnaround.zip.ZipUtil; +import org.zeroturnaround.zip.transform.StringZipEntryTransformer; +import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry; + public final class MixinRefmapHelper { - private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); - private MixinRefmapHelper() { + private MixinRefmapHelper() { } - } + public static boolean addRefmapName(String filename, String mixinVersion, Path outputPath) { + File output = outputPath.toFile(); + Set mixinFilenames = findMixins(output, true); - public static boolean addRefmapName(String filename, String mixinVersion, Path outputPath) { - File output = outputPath.toFile(); - Set mixinFilenames = findMixins(output, true); + if (mixinFilenames.size() > 0) { + return ZipUtil.transformEntries(output, mixinFilenames.stream().map((f) -> new ZipEntryTransformerEntry(f, new StringZipEntryTransformer("UTF-8") { + @Override + protected String transform(ZipEntry zipEntry, String input) throws IOException { + JsonObject json = GSON.fromJson(input, JsonObject.class); - if (mixinFilenames.size() > 0) { - return ZipUtil.transformEntries( - output, - mixinFilenames.stream() - .map((f) -> new ZipEntryTransformerEntry(f, new StringZipEntryTransformer("UTF-8") { - @Override - protected String transform(ZipEntry zipEntry, String input) throws IOException { - JsonObject json = GSON.fromJson(input, JsonObject.class); - if (!json.has("refmap")) { - json.addProperty("refmap", filename); - } - if (!json.has("minVersion") && mixinVersion != null) { - json.addProperty("minVersion", mixinVersion); - } - return GSON.toJson(json); - } - })).toArray(ZipEntryTransformerEntry[]::new) - ); - } else { - return false; - } - } + if (!json.has("refmap")) { + json.addProperty("refmap", filename); + } - private static Set findMixins(File output, boolean onlyWithoutRefmap) { - // first, identify all of the mixin files - Set mixinFilename = new HashSet<>(); - // TODO: this is a lovely hack - ZipUtil.iterate(output, (stream, entry) -> { - if (!entry.isDirectory() && entry.getName().endsWith(".json") && !entry.getName().contains("/") && !entry.getName().contains("\\")) { - // JSON file in root directory - try (InputStreamReader inputStreamReader = new InputStreamReader(stream)) { - JsonObject json = GSON.fromJson(inputStreamReader, JsonObject.class); + if (!json.has("minVersion") && mixinVersion != null) { + json.addProperty("minVersion", mixinVersion); + } - if (json != null) { - boolean hasMixins = json.has("mixins") && json.get("mixins").isJsonArray(); - boolean hasClient = json.has("client") && json.get("client").isJsonArray(); - boolean hasServer = json.has("server") && json.get("server").isJsonArray(); + return GSON.toJson(json); + } + })).toArray(ZipEntryTransformerEntry[]::new)); + } else { + return false; + } + } - if (json.has("package") && (hasMixins || hasClient || hasServer)) { - if (!onlyWithoutRefmap || !json.has("refmap") || !json.has("minVersion")) { - mixinFilename.add(entry.getName()); - } - } - } - } catch (Exception e) { - // ... - } - } - }); - return mixinFilename; - } + private static Set findMixins(File output, boolean onlyWithoutRefmap) { + // first, identify all of the mixin files + Set mixinFilename = new HashSet<>(); + // TODO: this is a lovely hack + ZipUtil.iterate(output, (stream, entry) -> { + if (!entry.isDirectory() && entry.getName().endsWith(".json") && !entry.getName().contains("/") && !entry.getName().contains("\\")) { + // JSON file in root directory + try (InputStreamReader inputStreamReader = new InputStreamReader(stream)) { + JsonObject json = GSON.fromJson(inputStreamReader, JsonObject.class); - private static Set findRefmaps(File output) { - // first, identify all of the mixin refmaps - Set mixinRefmapFilenames = new HashSet<>(); - // TODO: this is also a lovely hack - ZipUtil.iterate(output, (stream, entry) -> { - if (!entry.isDirectory() && entry.getName().endsWith(".json") && !entry.getName().contains("/") && !entry.getName().contains("\\")) { - // JSON file in root directory - try (InputStreamReader inputStreamReader = new InputStreamReader(stream)) { - JsonObject json = GSON.fromJson(inputStreamReader, JsonObject.class); - if (json != null && json.has("refmap")) { - mixinRefmapFilenames.add(json.get("refmap").getAsString()); - } - } catch (Exception e) { - // ... - } - } - }); - return mixinRefmapFilenames; - } + if (json != null) { + boolean hasMixins = json.has("mixins") && json.get("mixins").isJsonArray(); + boolean hasClient = json.has("client") && json.get("client").isJsonArray(); + boolean hasServer = json.has("server") && json.get("server").isJsonArray(); + + if (json.has("package") && (hasMixins || hasClient || hasServer)) { + if (!onlyWithoutRefmap || !json.has("refmap") || !json.has("minVersion")) { + mixinFilename.add(entry.getName()); + } + } + } + } catch (Exception e) { + // ... + } + } + }); + return mixinFilename; + } + + private static Set findRefmaps(File output) { + // first, identify all of the mixin refmaps + Set mixinRefmapFilenames = new HashSet<>(); + // TODO: this is also a lovely hack + ZipUtil.iterate(output, (stream, entry) -> { + if (!entry.isDirectory() && entry.getName().endsWith(".json") && !entry.getName().contains("/") && !entry.getName().contains("\\")) { + // JSON file in root directory + try (InputStreamReader inputStreamReader = new InputStreamReader(stream)) { + JsonObject json = GSON.fromJson(inputStreamReader, JsonObject.class); + + if (json != null && json.has("refmap")) { + mixinRefmapFilenames.add(json.get("refmap").getAsString()); + } + } catch (Exception e) { + // ... + } + } + }); + return mixinRefmapFilenames; + } } diff --git a/src/main/java/net/fabricmc/loom/util/ModCompileRemapper.java b/src/main/java/net/fabricmc/loom/util/ModCompileRemapper.java index 1433230..73cafaf 100644 --- a/src/main/java/net/fabricmc/loom/util/ModCompileRemapper.java +++ b/src/main/java/net/fabricmc/loom/util/ModCompileRemapper.java @@ -24,7 +24,11 @@ package net.fabricmc.loom.util; -import net.fabricmc.loom.LoomGradleExtension; +import java.io.File; +import java.io.IOException; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; + import org.gradle.api.Project; import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.Dependency; @@ -40,10 +44,7 @@ import org.gradle.api.logging.Logger; import org.gradle.jvm.JvmLibrary; import org.gradle.language.base.artifact.SourcesArtifact; -import java.io.File; -import java.io.IOException; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; +import net.fabricmc.loom.LoomGradleExtension; public class ModCompileRemapper { public static void remapDependencies(Project project, String mappingsPrefix, LoomGradleExtension extension, Configuration modCompile, Configuration modCompileRemapped, Configuration regularCompile, Consumer postPopulationScheduler) { @@ -93,7 +94,7 @@ public class ModCompileRemapper { } /** - * Checks if an artifact is a fabric mod, according to the presence of a fabric.mod.json + * Checks if an artifact is a fabric mod, according to the presence of a fabric.mod.json. */ private static boolean isFabricMod(Project project, Logger logger, ResolvedArtifact artifact, String notation) { File input = artifact.getFile(); @@ -112,15 +113,18 @@ public class ModCompileRemapper { project.getLogger().info(":providing " + notation); DependencyHandler dependencies = project.getDependencies(); Dependency dep = dependencies.module(notation); + if (dep instanceof ModuleDependency) { ((ModuleDependency) dep).setTransitive(false); } + dependencies.add(regularCompile.getName(), dep); } private static void remapArtifact(Project project, Configuration config, ResolvedArtifact artifact, String remappedFilename, File modStore) { File input = artifact.getFile(); File output = new File(modStore, remappedFilename + ".jar"); + if (!output.exists() || input.lastModified() <= 0 || input.lastModified() > output.lastModified()) { //If the output doesn't exist, or appears to be outdated compared to the input we'll remap it try { @@ -129,7 +133,7 @@ public class ModCompileRemapper { throw new RuntimeException("Failed to remap mod", e); } - if (!output.exists()){ + if (!output.exists()) { throw new RuntimeException("Failed to remap mod"); } @@ -142,10 +146,10 @@ public class ModCompileRemapper { } private static File findSources(DependencyHandler dependencies, ResolvedArtifact artifact) { - @SuppressWarnings ("unchecked") - ArtifactResolutionQuery query = dependencies.createArtifactResolutionQuery()// + @SuppressWarnings("unchecked") ArtifactResolutionQuery query = dependencies.createArtifactResolutionQuery()// .forComponents(artifact.getId().getComponentIdentifier())// .withArtifacts(JvmLibrary.class, SourcesArtifact.class); + for (ComponentArtifactsResult result : query.execute().getResolvedComponents()) { for (ArtifactResult srcArtifact : result.getArtifacts(SourcesArtifact.class)) { if (srcArtifact instanceof ResolvedArtifactResult) { @@ -153,6 +157,7 @@ public class ModCompileRemapper { } } } + return null; } diff --git a/src/main/java/net/fabricmc/loom/util/ModProcessor.java b/src/main/java/net/fabricmc/loom/util/ModProcessor.java index 863bd77..cccd2b4 100644 --- a/src/main/java/net/fabricmc/loom/util/ModProcessor.java +++ b/src/main/java/net/fabricmc/loom/util/ModProcessor.java @@ -24,23 +24,6 @@ package net.fabricmc.loom.util; -import com.google.gson.Gson; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.providers.MappingsProvider; -import net.fabricmc.loom.providers.MinecraftMappedProvider; -import net.fabricmc.tinyremapper.OutputConsumerPath; -import net.fabricmc.tinyremapper.TinyRemapper; -import org.apache.commons.io.IOUtils; -import org.gradle.api.Project; -import org.gradle.api.artifacts.Configuration; -import org.gradle.internal.impldep.aQute.lib.strings.Strings; -import org.zeroturnaround.zip.ZipUtil; -import org.zeroturnaround.zip.commons.FileUtils; -import org.zeroturnaround.zip.transform.StringZipEntryTransformer; -import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry; - import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -54,18 +37,39 @@ import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.zip.ZipEntry; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import org.apache.commons.io.IOUtils; +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; +import net.fabricmc.loom.providers.MinecraftMappedProvider; +import net.fabricmc.tinyremapper.OutputConsumerPath; +import net.fabricmc.tinyremapper.TinyRemapper; + public class ModProcessor { private static final Gson GSON = new Gson(); public static void processMod(File input, File output, Project project, Configuration config) throws IOException { - if(output.exists()){ + if (output.exists()) { output.delete(); } + remapJar(input, output, project); + //Enable this if you want your nested jars to be extracted, this will extract **all** jars - if(project.getExtensions().getByType(LoomGradleExtension.class).extractJars){ + if (project.getExtensions().getByType(LoomGradleExtension.class).extractJars) { handleNestedJars(input, project, config); } + //Always strip the nested jars stripNestedJars(output); } @@ -77,15 +81,20 @@ public class ModProcessor { private static void handleNestedJars(File input, Project project, Configuration config) throws IOException { JarFile jarFile = new JarFile(input); JarEntry modJsonEntry = jarFile.getJarEntry("fabric.mod.json"); - if(modJsonEntry == null){ + + if (modJsonEntry == null) { return; } - try(InputStream inputStream = jarFile.getInputStream(modJsonEntry)){ + + try (InputStream inputStream = jarFile.getInputStream(modJsonEntry)) { JsonObject json = GSON.fromJson(new InputStreamReader(inputStream), JsonObject.class); - if(json == null || !json.has("jars")){ + + if (json == null || !json.has("jars")) { return; } + JsonArray jsonArray = json.getAsJsonArray("jars"); + for (int i = 0; i < jsonArray.size(); i++) { JsonObject jsonObject = jsonArray.get(i).getAsJsonObject(); String fileName = jsonObject.get("file").getAsString(); @@ -99,19 +108,22 @@ public class ModProcessor { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); 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())); } File nestedFile = new File(extension.getNestedModCache(), fileName.substring(fileName.lastIndexOf("/"))); - try(InputStream jarStream = parentJar.getInputStream(entry)) { + + try (InputStream jarStream = parentJar.getInputStream(entry)) { FileUtils.copy(jarStream, nestedFile); } + File remappedFile = new File(extension.getRemappedModCache(), fileName.substring(fileName.lastIndexOf("/"))); processMod(nestedFile, remappedFile, project, config); - if(!remappedFile.exists()){ + if (!remappedFile.exists()) { throw new RuntimeException("Failed to find processed nested jar"); } @@ -119,7 +131,7 @@ public class ModProcessor { project.getDependencies().add(config.getName(), project.files(remappedFile)); } - 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. ZipUtil.transformEntries(file, new ZipEntryTransformerEntry[]{(new ZipEntryTransformerEntry("fabric.mod.json", new StringZipEntryTransformer() { @Override @@ -143,29 +155,22 @@ public class ModProcessor { 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); + Path[] mcDeps = mappedProvider.getMapperPaths().stream().map(File::toPath).toArray(Path[]::new); Set modCompiles = new HashSet<>(); - for (RemappedConfigurationEntry entry : Constants.MOD_COMPILE_ENTRIES) { - project.getConfigurations().getByName(entry.getSourceConfiguration()).getFiles().stream() - .filter((f) -> !f.equals(input)) - .map(p -> { - if (p.equals(input)) { - return inputPath; - } else { - return p.toPath(); - } - }) - .forEach(modCompiles::add); - } + for (RemappedConfigurationEntry entry : Constants.MOD_COMPILE_ENTRIES) { + project.getConfigurations().getByName(entry.getSourceConfiguration()).getFiles().stream().filter((f) -> !f.equals(input)).map(p -> { + if (p.equals(input)) { + return inputPath; + } else { + return p.toPath(); + } + }).forEach(modCompiles::add); + } 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)).build(); try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(Paths.get(output.getAbsolutePath())).build()) { outputConsumer.addNonClassFiles(inputPath); @@ -178,12 +183,12 @@ public class ModProcessor { remapper.finish(); } - if(!output.exists()){ + if (!output.exists()) { throw new RuntimeException("Failed to remap JAR to " + toM + " file not found: " + output.getAbsolutePath()); } } - static void readInstallerJson(File file, Project project){ + static void readInstallerJson(File file, Project project) { try { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); String launchMethod = extension.getLoaderLaunchMethod(); @@ -193,8 +198,10 @@ public class ModProcessor { try (JarFile jarFile = new JarFile(file)) { ZipEntry entry = null; + if (!launchMethod.isEmpty()) { entry = jarFile.getEntry("fabric-installer." + launchMethod + ".json"); + if (entry == null) { project.getLogger().warn("Could not find loader launch method '" + launchMethod + "', falling back"); } @@ -203,6 +210,7 @@ public class ModProcessor { if (entry == null) { entry = jarFile.getEntry("fabric-installer.json"); priority++; + if (entry == null) { return; } diff --git a/src/main/java/net/fabricmc/loom/util/NestedJars.java b/src/main/java/net/fabricmc/loom/util/NestedJars.java index e1b6910..48d2a25 100644 --- a/src/main/java/net/fabricmc/loom/util/NestedJars.java +++ b/src/main/java/net/fabricmc/loom/util/NestedJars.java @@ -24,28 +24,6 @@ package net.fabricmc.loom.util; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; - -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.task.RemapJarTask; - -import org.apache.commons.io.FileUtils; -import org.gradle.api.Project; -import org.gradle.api.Task; -import org.gradle.api.artifacts.Configuration; -import org.gradle.api.artifacts.Dependency; -import org.gradle.api.artifacts.DependencySet; -import org.gradle.api.artifacts.ProjectDependency; -import org.gradle.api.tasks.bundling.AbstractArchiveTask; -import org.zeroturnaround.zip.FileSource; -import org.zeroturnaround.zip.ZipEntrySource; -import org.zeroturnaround.zip.ZipUtil; -import org.zeroturnaround.zip.transform.StringZipEntryTransformer; -import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry; - import java.io.File; import java.io.IOException; import java.nio.file.Path; @@ -56,8 +34,28 @@ import java.util.Locale; import java.util.Set; import java.util.zip.ZipEntry; -public class NestedJars { +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import org.apache.commons.io.FileUtils; +import org.zeroturnaround.zip.FileSource; +import org.zeroturnaround.zip.ZipEntrySource; +import org.zeroturnaround.zip.ZipUtil; +import org.zeroturnaround.zip.transform.StringZipEntryTransformer; +import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry; +import org.gradle.api.Project; +import org.gradle.api.Task; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.artifacts.Dependency; +import org.gradle.api.artifacts.DependencySet; +import org.gradle.api.artifacts.ProjectDependency; +import org.gradle.api.tasks.bundling.AbstractArchiveTask; +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.task.RemapJarTask; + +public class NestedJars { private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); public static boolean addNestedJars(Project project, Path modJarPath) { @@ -74,6 +72,7 @@ public class NestedJars { protected String transform(ZipEntry zipEntry, String input) throws IOException { JsonObject json = GSON.fromJson(input, JsonObject.class); JsonArray nestedJars = json.getAsJsonArray("jars"); + if (nestedJars == null || !json.has("jars")) { nestedJars = new JsonArray(); } @@ -96,6 +95,7 @@ public class NestedJars { Configuration configuration = project.getConfigurations().getByName(Constants.INCLUDE); DependencySet dependencies = configuration.getDependencies(); + for (Dependency dependency : dependencies) { if (dependency instanceof ProjectDependency) { ProjectDependency projectDependency = (ProjectDependency) dependency; @@ -116,27 +116,32 @@ public class NestedJars { fileList.addAll(prepareForNesting(configuration.files(dependency), dependency, project)); } } + for (File file : fileList) { if (!file.exists()) { throw new RuntimeException("Failed to include nested jars, as it could not be found @ " + file.getAbsolutePath()); } + if (file.isDirectory() || !file.getName().endsWith(".jar")) { throw new RuntimeException("Failed to include nested jars, as file was not a jar: " + file.getAbsolutePath()); } } + return fileList; } //Looks for any deps that require a sub project to be built first - public static List getRequiredTasks(Project project){ + public static List getRequiredTasks(Project project) { List remapTasks = new ArrayList<>(); Configuration configuration = project.getConfigurations().getByName(Constants.INCLUDE); DependencySet dependencies = configuration.getDependencies(); + for (Dependency dependency : dependencies) { if (dependency instanceof ProjectDependency) { ProjectDependency projectDependency = (ProjectDependency) dependency; Project dependencyProject = projectDependency.getDependencyProject(); + for (Task task : dependencyProject.getTasksByName("remapJar", false)) { if (task instanceof RemapJarTask) { remapTasks.add((RemapJarTask) task); @@ -144,29 +149,36 @@ public class NestedJars { } } } + return remapTasks; } //This is a good place to do pre-nesting operations, such as adding a fabric.mod.json to a library - private static List prepareForNesting(Set files, Dependency dependency, Project project){ + private static List prepareForNesting(Set files, Dependency dependency, Project project) { List fileList = new ArrayList<>(); - for(File file : files){ + + for (File file : files) { //A lib that doesnt have a mod.json, we turn it into a fake mod - if(!ZipUtil.containsEntry(file, "fabric.mod.json")){ + if (!ZipUtil.containsEntry(file, "fabric.mod.json")) { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); File tempDir = new File(extension.getUserCache(), "temp/modprocessing"); - if(!tempDir.exists()){ + + if (!tempDir.exists()) { tempDir.mkdirs(); } + File tempFile = new File(tempDir, file.getName()); - if(tempFile.exists()){ + + if (tempFile.exists()) { tempFile.delete(); } + try { FileUtils.copyFile(file, tempFile); } catch (IOException e) { throw new RuntimeException("Failed to copy file", e); } + ZipUtil.addEntry(tempFile, "fabric.mod.json", getMod(dependency).getBytes()); fileList.add(tempFile); } else { @@ -174,11 +186,12 @@ public class NestedJars { fileList.add(file); } } + return fileList; } //Generates a barebones mod for a dependency - private static String getMod(Dependency dependency){ + private static String getMod(Dependency dependency) { JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("schemaVersion", 1); jsonObject.addProperty("id", (dependency.getGroup().replaceAll("\\.", "_") + "_" + dependency.getName()).toLowerCase(Locale.ENGLISH)); diff --git a/src/main/java/net/fabricmc/loom/util/OperatingSystem.java b/src/main/java/net/fabricmc/loom/util/OperatingSystem.java index 395b5ea..727948f 100644 --- a/src/main/java/net/fabricmc/loom/util/OperatingSystem.java +++ b/src/main/java/net/fabricmc/loom/util/OperatingSystem.java @@ -27,6 +27,7 @@ package net.fabricmc.loom.util; public class OperatingSystem { public static String getOS() { String osName = System.getProperty("os.name").toLowerCase(); + if (osName.contains("win")) { return "windows"; } else if (osName.contains("mac")) { diff --git a/src/main/java/net/fabricmc/loom/util/RemappedConfigurationEntry.java b/src/main/java/net/fabricmc/loom/util/RemappedConfigurationEntry.java index d6e01ee..767c3a8 100644 --- a/src/main/java/net/fabricmc/loom/util/RemappedConfigurationEntry.java +++ b/src/main/java/net/fabricmc/loom/util/RemappedConfigurationEntry.java @@ -27,43 +27,43 @@ package net.fabricmc.loom.util; import org.gradle.api.artifacts.ConfigurationContainer; public class RemappedConfigurationEntry { - private final String sourceConfiguration; - private final String targetConfiguration; - private final String mavenScope; - private final boolean isOnModCompileClasspath; + private final String sourceConfiguration; + private final String targetConfiguration; + private final String mavenScope; + private final boolean isOnModCompileClasspath; - public RemappedConfigurationEntry(String sourceConfiguration, String targetConfiguration, boolean isOnModCompileClasspath, String mavenScope) { - this.sourceConfiguration = sourceConfiguration; - this.targetConfiguration = targetConfiguration; - this.isOnModCompileClasspath = isOnModCompileClasspath; - this.mavenScope = mavenScope; - } + public RemappedConfigurationEntry(String sourceConfiguration, String targetConfiguration, boolean isOnModCompileClasspath, String mavenScope) { + this.sourceConfiguration = sourceConfiguration; + this.targetConfiguration = targetConfiguration; + this.isOnModCompileClasspath = isOnModCompileClasspath; + this.mavenScope = mavenScope; + } - public String getMavenScope() { - return mavenScope; - } + public String getMavenScope() { + return mavenScope; + } - public boolean hasMavenScope() { - return mavenScope != null && !mavenScope.isEmpty(); - } + public boolean hasMavenScope() { + return mavenScope != null && !mavenScope.isEmpty(); + } - public boolean isOnModCompileClasspath() { - return isOnModCompileClasspath; - } + public boolean isOnModCompileClasspath() { + return isOnModCompileClasspath; + } - public String getSourceConfiguration() { - return sourceConfiguration; - } + public String getSourceConfiguration() { + return sourceConfiguration; + } - public String getRemappedConfiguration() { - return sourceConfiguration + "Mapped"; - } + public String getRemappedConfiguration() { + return sourceConfiguration + "Mapped"; + } - public String getTargetConfiguration(ConfigurationContainer container) { - if (container.findByName(targetConfiguration) == null) { - return "compile"; - } + public String getTargetConfiguration(ConfigurationContainer container) { + if (container.findByName(targetConfiguration) == null) { + return "compile"; + } - return targetConfiguration; - } + return targetConfiguration; + } } diff --git a/src/main/java/net/fabricmc/loom/util/RunConfig.java b/src/main/java/net/fabricmc/loom/util/RunConfig.java index c26f8d0..2b52459 100644 --- a/src/main/java/net/fabricmc/loom/util/RunConfig.java +++ b/src/main/java/net/fabricmc/loom/util/RunConfig.java @@ -24,21 +24,6 @@ package net.fabricmc.loom.util; -import com.google.common.base.Strings; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.providers.MinecraftProvider; -import org.apache.commons.io.IOUtils; -import org.gradle.api.Project; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerException; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -47,6 +32,23 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; + +import com.google.common.base.Strings; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import org.apache.commons.io.IOUtils; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.gradle.api.Project; + +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.providers.MinecraftProvider; + public class RunConfig { public String configName; public String projectName; @@ -70,19 +72,23 @@ public class RunConfig { if (!Strings.isNullOrEmpty(programArgs)) { this.addXml(root, "option", ImmutableMap.of("name", "PROGRAM_PARAMETERS", "value", programArgs)); } + return root; } public Element addXml(Node parent, String name, Map values) { Document doc = parent.getOwnerDocument(); + if (doc == null) { doc = (Document) parent; } Element e = doc.createElement(name); + for (Map.Entry entry : values.entrySet()) { e.setAttribute(entry.getKey(), entry.getValue()); } + parent.appendChild(e); return e; } @@ -90,29 +96,32 @@ public class RunConfig { private static void populate(Project project, LoomGradleExtension extension, RunConfig runConfig, String mode) { runConfig.projectName = project.getName(); runConfig.runDir = "file://$PROJECT_DIR$/" + extension.runDir; - runConfig.vmArgs = "-Dfabric.development=true -Djava.library.path=\"" + extension.getNativesDirectory().getAbsolutePath() + "\""; + runConfig.vmArgs = "-Dfabric.development=true -Djava.library.path=\"" + extension.getNativesDirectory().getAbsolutePath() + "\""; switch (extension.getLoaderLaunchMethod()) { - case "launchwrapper": - runConfig.mainClass = "net.minecraft.launchwrapper.Launch"; - runConfig.programArgs = "--tweakClass " + ("client".equals(mode) ? Constants.DEFAULT_FABRIC_CLIENT_TWEAKER : Constants.DEFAULT_FABRIC_SERVER_TWEAKER); - break; - default: - runConfig.mainClass = "net.fabricmc.loader.launch.knot.Knot" + mode.substring(0, 1).toUpperCase(Locale.ROOT) + mode.substring(1).toLowerCase(Locale.ROOT); - runConfig.programArgs = ""; - break; + case "launchwrapper": + runConfig.mainClass = "net.minecraft.launchwrapper.Launch"; + runConfig.programArgs = "--tweakClass " + ("client".equals(mode) ? Constants.DEFAULT_FABRIC_CLIENT_TWEAKER : Constants.DEFAULT_FABRIC_SERVER_TWEAKER); + break; + default: + runConfig.mainClass = "net.fabricmc.loader.launch.knot.Knot" + mode.substring(0, 1).toUpperCase(Locale.ROOT) + mode.substring(1).toLowerCase(Locale.ROOT); + runConfig.programArgs = ""; + break; } // if installer.json found... JsonObject installerJson = extension.getInstallerJson(); + if (installerJson != null) { List sideKeys = ImmutableList.of(mode, "common"); // copy main class if (installerJson.has("mainClass")) { JsonElement mainClassJson = installerJson.get("mainClass"); + if (mainClassJson.isJsonObject()) { JsonObject mainClassesJson = mainClassJson.getAsJsonObject(); + for (String s : sideKeys) { if (mainClassesJson.has(s)) { runConfig.mainClass = mainClassesJson.get(s).getAsString(); @@ -127,9 +136,11 @@ public class RunConfig { // copy launchwrapper tweakers if (installerJson.has("launchwrapper")) { JsonObject launchwrapperJson = installerJson.getAsJsonObject("launchwrapper"); + if (launchwrapperJson.has("tweakers")) { JsonObject tweakersJson = launchwrapperJson.getAsJsonObject("tweakers"); StringBuilder builder = new StringBuilder(); + for (String s : sideKeys) { if (tweakersJson.has(s)) { for (JsonElement element : tweakersJson.getAsJsonArray(s)) { @@ -137,15 +148,16 @@ public class RunConfig { } } } + runConfig.programArgs += builder.toString(); } } } } - public static RunConfig clientRunConfig(Project project){ + public static RunConfig clientRunConfig(Project project) { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); - MinecraftProvider minecraftProvider = extension.getMinecraftProvider(); + MinecraftProvider minecraftProvider = extension.getMinecraftProvider(); MinecraftVersionInfo minecraftVersionInfo = minecraftProvider.versionInfo; RunConfig ideaClient = new RunConfig(); @@ -157,7 +169,7 @@ public class RunConfig { return ideaClient; } - public static RunConfig serverRunConfig(Project project){ + public static RunConfig serverRunConfig(Project project) { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); RunConfig ideaServer = new RunConfig(); @@ -169,6 +181,7 @@ public class RunConfig { public String fromDummy(String dummy) throws IOException { String dummyConfig; + try (InputStream input = SetupIntelijRunConfigs.class.getClassLoader().getResourceAsStream(dummy)) { dummyConfig = IOUtils.toString(input, StandardCharsets.UTF_8); } @@ -182,10 +195,11 @@ public class RunConfig { return dummyConfig; } - public static String getOSClientJVMArgs(){ - if(OperatingSystem.getOS().equalsIgnoreCase("osx")){ + public static String getOSClientJVMArgs() { + if (OperatingSystem.getOS().equalsIgnoreCase("osx")) { return " -XstartOnFirstThread"; } + return ""; } -} \ No newline at end of file +} diff --git a/src/main/java/net/fabricmc/loom/util/SetupIntelijRunConfigs.java b/src/main/java/net/fabricmc/loom/util/SetupIntelijRunConfigs.java index 39d5222..f408b5f 100644 --- a/src/main/java/net/fabricmc/loom/util/SetupIntelijRunConfigs.java +++ b/src/main/java/net/fabricmc/loom/util/SetupIntelijRunConfigs.java @@ -24,25 +24,27 @@ package net.fabricmc.loom.util; -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.providers.MinecraftAssetsProvider; -import net.fabricmc.loom.providers.MinecraftNativesProvider; -import org.apache.commons.io.FileUtils; -import org.gradle.api.Project; - import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; -public class SetupIntelijRunConfigs { +import org.apache.commons.io.FileUtils; +import org.gradle.api.Project; +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.providers.MinecraftAssetsProvider; +import net.fabricmc.loom.providers.MinecraftNativesProvider; + +public class SetupIntelijRunConfigs { public static void setup(Project project) { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); File projectDir = project.file(".idea"); - if(!projectDir.exists()){ + + if (!projectDir.exists()) { return; } + try { generate(project); } catch (IOException e) { @@ -50,6 +52,7 @@ public class SetupIntelijRunConfigs { } File runDir = new File(project.getRootDir(), extension.runDir); + if (!runDir.exists()) { runDir.mkdirs(); } @@ -57,7 +60,7 @@ public class SetupIntelijRunConfigs { private static void generate(Project project) throws IOException { //Ensures the assets are downloaded when idea is syncing a project - if(Boolean.parseBoolean(System.getProperty("idea.sync.active", "false"))){ + if (Boolean.parseBoolean(System.getProperty("idea.sync.active", "false"))) { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); MinecraftAssetsProvider.provide(extension.getMinecraftProvider(), project); MinecraftNativesProvider.provide(extension.getMinecraftProvider(), project); @@ -68,18 +71,19 @@ public class SetupIntelijRunConfigs { File clientRunConfigs = new File(runConfigsDir, "Minecraft_Client.xml"); File serverRunConfigs = new File(runConfigsDir, "Minecraft_Server.xml"); - if(!runConfigsDir.exists()){ + if (!runConfigsDir.exists()) { runConfigsDir.mkdirs(); } String clientRunConfig = RunConfig.clientRunConfig(project).fromDummy("idea_run_config_template.xml"); String serverRunConfig = RunConfig.serverRunConfig(project).fromDummy("idea_run_config_template.xml"); - if(!clientRunConfigs.exists()) + if (!clientRunConfigs.exists()) { FileUtils.writeStringToFile(clientRunConfigs, clientRunConfig, StandardCharsets.UTF_8); - if(!serverRunConfigs.exists()) + } + + if (!serverRunConfigs.exists()) { FileUtils.writeStringToFile(serverRunConfigs, serverRunConfig, StandardCharsets.UTF_8); - + } } - } diff --git a/src/main/java/net/fabricmc/loom/util/SourceRemapper.java b/src/main/java/net/fabricmc/loom/util/SourceRemapper.java index 67d05c8..419e364 100644 --- a/src/main/java/net/fabricmc/loom/util/SourceRemapper.java +++ b/src/main/java/net/fabricmc/loom/util/SourceRemapper.java @@ -24,31 +24,26 @@ package net.fabricmc.loom.util; -import com.google.common.collect.ImmutableMap; -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.providers.MappingsProvider; -import net.fabricmc.mappings.*; -import net.fabricmc.stitch.util.Pair; -import net.fabricmc.stitch.util.StitchUtil; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + import org.cadixdev.lorenz.MappingSet; import org.cadixdev.lorenz.io.MappingsReader; -import org.cadixdev.lorenz.io.TextMappingsReader; -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.internal.impldep.aQute.bnd.build.Run; -import org.objectweb.asm.commons.Remapper; import org.zeroturnaround.zip.ZipUtil; +import org.gradle.api.Project; -import java.io.*; -import java.net.URI; -import java.nio.file.*; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +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.stitch.util.StitchUtil; public class SourceRemapper { public static void remapSources(Project project, File source, File destination, boolean toNamed) throws Exception { @@ -79,11 +74,13 @@ public class SourceRemapper { 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()) { if (Files.isRegularFile(file)) { m.getClassPath().add(file); @@ -104,6 +101,7 @@ public class SourceRemapper { } source = new File(destination.getAbsolutePath().substring(0, destination.getAbsolutePath().lastIndexOf('.')) + "-dev.jar"); + try { com.google.common.io.Files.move(destination, source); } catch (IOException e) { @@ -113,6 +111,7 @@ public class SourceRemapper { Path srcPath = source.toPath(); boolean isSrcTmp = false; + if (!source.isDirectory()) { // create tmp directory isSrcTmp = true; @@ -144,27 +143,27 @@ public class SourceRemapper { if (isSrcTmp) { Files.walkFileTree(srcPath, new DeletingFileVisitor()); } - } - private static void copyNonJavaFiles(Path from, Path to, Project project, File source) throws IOException { - Files.walk(from).forEach(path -> { - Path targetPath = to.resolve(from.relativize(path).toString()); - if (!isJavaFile(path) && !Files.exists(targetPath)) { - try { - Files.copy(path, targetPath); - } catch (IOException e) { - project.getLogger().warn("Could not copy non-java sources '" + source.getName() + "' fully!", e); - } - } - }); - } + private static void copyNonJavaFiles(Path from, Path to, Project project, File source) throws IOException { + Files.walk(from).forEach(path -> { + Path targetPath = to.resolve(from.relativize(path).toString()); - private static boolean isJavaFile(Path path) { - String name = path.getFileName().toString(); - // ".java" is not a valid java file - return name.endsWith(".java") && name.length() != 5; - } + if (!isJavaFile(path) && !Files.exists(targetPath)) { + try { + Files.copy(path, targetPath); + } catch (IOException e) { + project.getLogger().warn("Could not copy non-java sources '" + source.getName() + "' fully!", e); + } + } + }); + } + + private static boolean isJavaFile(Path path) { + String name = path.getFileName().toString(); + // ".java" is not a valid java file + return name.endsWith(".java") && name.length() != 5; + } public static class TinyReader extends MappingsReader { private final Mappings m; @@ -179,35 +178,27 @@ public class SourceRemapper { @Override public MappingSet read(final MappingSet mappings) { for (ClassEntry entry : m.getClassEntries()) { - mappings.getOrCreateClassMapping(entry.get(from)) - .setDeobfuscatedName(entry.get(to)); + mappings.getOrCreateClassMapping(entry.get(from)).setDeobfuscatedName(entry.get(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()); + 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()); + mappings.getOrCreateClassMapping(fromEntry.getOwner()).getOrCreateMethodMapping(fromEntry.getName(), fromEntry.getDesc()).setDeobfuscatedName(toEntry.getName()); } return mappings; } @Override - public void close() throws IOException { - - } + public void close() throws IOException { } } - } diff --git a/src/main/java/net/fabricmc/loom/util/StaticPathWatcher.java b/src/main/java/net/fabricmc/loom/util/StaticPathWatcher.java index cb8d009..751d6ce 100644 --- a/src/main/java/net/fabricmc/loom/util/StaticPathWatcher.java +++ b/src/main/java/net/fabricmc/loom/util/StaticPathWatcher.java @@ -24,63 +24,66 @@ package net.fabricmc.loom.util; -import net.fabricmc.mappings.Mappings; -import org.gradle.api.logging.Logging; - import java.io.IOException; -import java.io.InputStream; -import java.lang.ref.SoftReference; -import java.nio.file.*; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardWatchEventKinds; +import java.nio.file.WatchEvent; +import java.nio.file.WatchKey; +import java.nio.file.WatchService; import java.util.HashMap; import java.util.Map; public final class StaticPathWatcher { - public static final StaticPathWatcher INSTANCE = new StaticPathWatcher(); + public static final StaticPathWatcher INSTANCE = new StaticPathWatcher(); - private final Map changeCache = new HashMap<>(); - private final WatchService service; - private final Map pathsObserved = new HashMap<>(); + private final Map changeCache = new HashMap<>(); + private final WatchService service; + private final Map pathsObserved = new HashMap<>(); - private StaticPathWatcher() { - try { - service = FileSystems.getDefault().newWatchService(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } + private StaticPathWatcher() { + try { + service = FileSystems.getDefault().newWatchService(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } - public boolean hasFileChanged(Path filePath) { - if(!Files.exists(filePath)){ - return true; - } - WatchKey key; - while ((key = service.poll()) != null) { - for (WatchEvent event : key.pollEvents()) { - Object ctx = event.context(); - if (ctx instanceof Path) { - changeCache.put(((Path) ctx).toAbsolutePath(), true); - } - } - } + public boolean hasFileChanged(Path filePath) { + if (!Files.exists(filePath)) { + return true; + } - filePath = filePath.toAbsolutePath(); - Path parentPath = filePath.getParent(); - if (changeCache.containsKey(filePath)) { - return true; - } else { - if (!pathsObserved.containsKey(parentPath)) { - try { - pathsObserved.put(parentPath, parentPath.register( - service, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE - )); + WatchKey key; - return true; - } catch (IOException e) { - throw new RuntimeException(e); - } - } else { - return false; - } - } - } + while ((key = service.poll()) != null) { + for (WatchEvent event : key.pollEvents()) { + Object ctx = event.context(); + + if (ctx instanceof Path) { + changeCache.put(((Path) ctx).toAbsolutePath(), true); + } + } + } + + filePath = filePath.toAbsolutePath(); + Path parentPath = filePath.getParent(); + + if (changeCache.containsKey(filePath)) { + return true; + } else { + if (!pathsObserved.containsKey(parentPath)) { + try { + pathsObserved.put(parentPath, parentPath.register(service, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE)); + + return true; + } catch (IOException e) { + throw new RuntimeException(e); + } + } else { + return false; + } + } + } } diff --git a/src/main/java/net/fabricmc/loom/util/TinyRemapperMappingsHelper.java b/src/main/java/net/fabricmc/loom/util/TinyRemapperMappingsHelper.java index 6b4f105..0652e52 100644 --- a/src/main/java/net/fabricmc/loom/util/TinyRemapperMappingsHelper.java +++ b/src/main/java/net/fabricmc/loom/util/TinyRemapperMappingsHelper.java @@ -24,14 +24,16 @@ package net.fabricmc.loom.util; -import net.fabricmc.mappings.*; +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.tinyremapper.IMappingProvider; import net.fabricmc.tinyremapper.MemberInstance; public class TinyRemapperMappingsHelper { - private TinyRemapperMappingsHelper() { - - } + private TinyRemapperMappingsHelper() { } public static IMappingProvider create(Mappings mappings, String from, String to) { return (classMap, fieldMap, methodMap) -> { diff --git a/src/main/java/net/fabricmc/loom/util/Version.java b/src/main/java/net/fabricmc/loom/util/Version.java index 6fbfe24..a6842e3 100644 --- a/src/main/java/net/fabricmc/loom/util/Version.java +++ b/src/main/java/net/fabricmc/loom/util/Version.java @@ -25,7 +25,6 @@ package net.fabricmc.loom.util; public class Version { - private String mappingsVersion; private String minecraftVersion; @@ -34,7 +33,7 @@ public class Version { public Version(String version) { this.version = version; - if(version.contains("+build.")){ + if (version.contains("+build.")) { this.minecraftVersion = version.substring(0, version.lastIndexOf('+')); this.mappingsVersion = version.substring(version.lastIndexOf('.') + 1); } else { @@ -57,4 +56,4 @@ public class Version { public String toString() { return version; } -} \ No newline at end of file +} diff --git a/src/main/java/net/fabricmc/loom/util/assets/AssetObject.java b/src/main/java/net/fabricmc/loom/util/assets/AssetObject.java index f7d446e..087f4ac 100644 --- a/src/main/java/net/fabricmc/loom/util/assets/AssetObject.java +++ b/src/main/java/net/fabricmc/loom/util/assets/AssetObject.java @@ -54,4 +54,4 @@ public class AssetObject { result = 31 * result + (int) (this.size ^ this.size >>> 32); return result; } -} \ No newline at end of file +} diff --git a/src/main/java/net/fabricmc/loom/util/progress/ProgressLogger.java b/src/main/java/net/fabricmc/loom/util/progress/ProgressLogger.java index f7ffcb4..b43e955 100644 --- a/src/main/java/net/fabricmc/loom/util/progress/ProgressLogger.java +++ b/src/main/java/net/fabricmc/loom/util/progress/ProgressLogger.java @@ -24,13 +24,13 @@ package net.fabricmc.loom.util.progress; -import org.gradle.api.Project; - import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import org.gradle.api.Project; + /** - * Wrapper to ProgressLogger internal API + * Wrapper to ProgressLogger internal API. */ public class ProgressLogger { private final Object logger; @@ -54,6 +54,7 @@ public class ProgressLogger { private static Class getFactoryClass() { Class progressLoggerFactoryClass = null; + try { //Gradle 2.14 and higher progressLoggerFactoryClass = Class.forName("org.gradle.internal.logging.progress.ProgressLoggerFactory"); @@ -65,6 +66,7 @@ public class ProgressLogger { // Unsupported Gradle version } } + return progressLoggerFactoryClass; } @@ -73,9 +75,10 @@ public class ProgressLogger { try { return logger.getClass().getMethod(methodName, args); } catch (NoSuchMethodException ignored) { - + //Nope } } + return null; } @@ -85,14 +88,15 @@ public class ProgressLogger { method.setAccessible(true); return method.invoke(logger, args); } catch (IllegalAccessException | InvocationTargetException ignored) { - + //Nope } } + return null; } /** - * Get a Progress logger from the Gradle internal API + * Get a Progress logger from the Gradle internal API. * * @param project The project * @param category The logger category @@ -122,9 +126,9 @@ public class ProgressLogger { } /** - *

Sets the description of the operation. This should be a full, stand-alone description of the operation. - *

- *

This must be called before {@link #started()}. + * Sets the description of the operation. This should be a full, stand-alone description of the operation. + * + *

This must be called before {@link #started()} * * @param description The description. */ @@ -143,8 +147,8 @@ public class ProgressLogger { } /** - *

Sets the short description of the operation. This is used in place of the full description when display space is limited. - *

+ * Sets the short description of the operation. This is used in place of the full description when display space is limited. + * *

This must be called before {@link #started()} * * @param description The short description. @@ -155,9 +159,9 @@ public class ProgressLogger { } /** - *

Returns the logging header for the operation. This is logged before any other log messages for this operation are logged. It is usually + * Returns the logging header for the operation. This is logged before any other log messages for this operation are logged. It is usually * also logged at the end of the operation, along with the final status message. Defaults to null. - *

+ * *

If not specified, no logging header is logged. * * @return The logging header, possibly empty. @@ -167,7 +171,7 @@ public class ProgressLogger { } /** - *

Sets the logging header for the operation. This is logged before any other log messages for this operation are logged. It is usually + * Sets the logging header for the operation. This is logged before any other log messages for this operation are logged. It is usually * also logged at the end of the operation, along with the final status message. Defaults to null. * * @param header The header. May be empty or null. @@ -213,7 +217,7 @@ public class ProgressLogger { } /** - * Logs the completion of the operation, with no final status + * Logs the completion of the operation, with no final status. */ public void completed() { invoke(completed);