diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 91ca28c..29953ea 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/src/main/java/net/fabricmc/loom/AbstractPlugin.java b/src/main/java/net/fabricmc/loom/AbstractPlugin.java index 99891e5..5e275d5 100644 --- a/src/main/java/net/fabricmc/loom/AbstractPlugin.java +++ b/src/main/java/net/fabricmc/loom/AbstractPlugin.java @@ -26,7 +26,6 @@ package net.fabricmc.loom; import com.google.common.collect.ImmutableMap; import com.google.gson.Gson; -import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import net.fabricmc.loom.task.DownloadTask; @@ -36,6 +35,7 @@ import net.fabricmc.loom.util.Version; import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.Task; +import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.repositories.MavenArtifactRepository; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPluginConvention; @@ -78,9 +78,10 @@ public class AbstractPlugin implements Plugin { project.getConfigurations().maybeCreate(Constants.CONFIG_MC_DEPENDENCIES); project.getConfigurations().maybeCreate(Constants.CONFIG_MC_DEPENDENCIES_CLIENT); project.getConfigurations().maybeCreate(Constants.CONFIG_NATIVES); - project.getConfigurations().maybeCreate(Constants.COMPILE_MODS); + Configuration compileModsConfig = project.getConfigurations().maybeCreate(Constants.COMPILE_MODS); + project.getConfigurations().maybeCreate(Constants.COMPILE_MODS_PROCESSED); - project.getConfigurations().maybeCreate(Constants.PROCESS_MODS_DEPENDENCIES); + compileModsConfig.setTransitive(false); //Dont get transitive deps of mods // Common libraries extends from client libraries, CONFIG_MC_DEPENDENCIES will contains all MC dependencies project.getConfigurations().getByName(Constants.CONFIG_MINECRAFT).extendsFrom(project.getConfigurations().getByName(Constants.CONFIG_MC_DEPENDENCIES).extendsFrom(project.getConfigurations().getByName(Constants.CONFIG_MC_DEPENDENCIES_CLIENT))); @@ -88,6 +89,7 @@ public class AbstractPlugin implements Plugin { configureIDEs(); configureCompile(); + Map> taskMap = project.getAllTasks(true); for (Map.Entry> entry : taskMap.entrySet()) { Project project = entry.getKey(); @@ -170,12 +172,12 @@ public class AbstractPlugin implements Plugin { ideaModule.getModule().setDownloadSources(true); ideaModule.getModule().setInheritOutputDirs(true); ideaModule.getModule().getScopes().get("COMPILE").get("plus").add(project.getConfigurations().getByName(Constants.CONFIG_MINECRAFT)); - ideaModule.getModule().getScopes().get("COMPILE").get("plus").add(project.getConfigurations().getByName(Constants.COMPILE_MODS)); + ideaModule.getModule().getScopes().get("COMPILE").get("plus").add(project.getConfigurations().getByName(Constants.COMPILE_MODS_PROCESSED)); // ECLIPSE EclipseModel eclipseModule = (EclipseModel) project.getExtensions().getByName("eclipse"); eclipseModule.getClasspath().getPlusConfigurations().add(project.getConfigurations().getByName(Constants.CONFIG_MINECRAFT)); - eclipseModule.getClasspath().getPlusConfigurations().add(project.getConfigurations().getByName(Constants.COMPILE_MODS)); + eclipseModule.getClasspath().getPlusConfigurations().add(project.getConfigurations().getByName(Constants.COMPILE_MODS_PROCESSED)); } /** @@ -208,11 +210,6 @@ public class AbstractPlugin implements Plugin { flatDirectoryArtifactRepository.setName("UserLocalCacheFiles"); }); - project1.getRepositories().maven(mavenArtifactRepository -> { - mavenArtifactRepository.setName("FabricMC"); - mavenArtifactRepository.setUrl("http://maven.fabricmc.net/"); - }); - project1.getRepositories().maven(mavenArtifactRepository -> { mavenArtifactRepository.setName("modmuss50"); mavenArtifactRepository.setUrl("https://maven.modmuss50.me/"); @@ -251,8 +248,10 @@ public class AbstractPlugin implements Plugin { if (extension.isModWorkspace()) { //only add this when not in a dev env - project1.getDependencies().add(Constants.CONFIG_MC_DEPENDENCIES, "net.fabricmc:fabric-base:" + extension.getVersionString() +":deobf"); + project1.getDependencies().add(Constants.COMPILE_MODS, "net.fabricmc:fabric-base:" + extension.getVersionString()); } + + }); project.getTasks().getByName("jar").doLast(task -> { diff --git a/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java b/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java index 6767b22..26a70e0 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java +++ b/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java @@ -25,10 +25,7 @@ package net.fabricmc.loom; import net.fabricmc.loom.task.*; -import net.fabricmc.loom.util.Constants; -import org.gradle.api.DefaultTask; import org.gradle.api.Project; -import org.gradle.api.Task; public class LoomGradlePlugin extends AbstractPlugin { @Override @@ -39,7 +36,7 @@ public class LoomGradlePlugin extends AbstractPlugin { makeTask("mergeJars", MergeJarsTask.class).dependsOn("download"); makeTask("mapJars", MapJarsTask.class).dependsOn("mergeJars"); makeTask("finaliseJars", FinaliseJar.class).dependsOn("mapJars"); - makeTask("setup", DefaultTask.class).dependsOn("finaliseJars").setGroup("fabric"); + makeTask("setup", SetupTask.class).dependsOn("finaliseJars").setGroup("fabric"); makeTask("extractNatives", ExtractNativesTask.class).dependsOn("download"); makeTask("genIdeaWorkspace", GenIdeaProjectTask.class).dependsOn("idea").setGroup("ide"); diff --git a/src/main/java/net/fabricmc/loom/task/MapJarsTask.java b/src/main/java/net/fabricmc/loom/task/MapJarsTask.java index 2baf1a0..f6dd4d9 100644 --- a/src/main/java/net/fabricmc/loom/task/MapJarsTask.java +++ b/src/main/java/net/fabricmc/loom/task/MapJarsTask.java @@ -31,10 +31,14 @@ import org.gradle.api.tasks.TaskAction; import org.zeroturnaround.zip.commons.FileUtils; public class MapJarsTask extends DefaultTask { + + //Set to to true if you want to always remap the jar, useful for when working on the gradle plugin + public static final boolean ALWAYS_REMAP = false; + @TaskAction public void mapJars() throws Exception { LoomGradleExtension extension = this.getProject().getExtensions().getByType(LoomGradleExtension.class); - if (!Constants.MINECRAFT_MAPPED_JAR.get(extension).exists() || extension.localMappings || true) { + if (!Constants.MINECRAFT_MAPPED_JAR.get(extension).exists() || extension.localMappings || ALWAYS_REMAP) { if(Constants.MINECRAFT_MAPPED_JAR.get(extension).exists()){ Constants.MINECRAFT_MAPPED_JAR.get(extension).delete(); } diff --git a/src/main/java/net/fabricmc/loom/task/MapJarsTiny.java b/src/main/java/net/fabricmc/loom/task/MapJarsTiny.java index 7ea9e50..44b94a7 100644 --- a/src/main/java/net/fabricmc/loom/task/MapJarsTiny.java +++ b/src/main/java/net/fabricmc/loom/task/MapJarsTiny.java @@ -30,10 +30,6 @@ import net.fabricmc.loom.util.Constants; import net.fabricmc.tinyremapper.OutputConsumerPath; import net.fabricmc.tinyremapper.TinyRemapper; import net.fabricmc.tinyremapper.TinyUtils; -import org.gradle.api.DefaultTask; -import org.gradle.api.tasks.TaskAction; -import org.zeroturnaround.zip.ZipUtil; -import org.zeroturnaround.zip.commons.FileUtils; import java.io.File; import java.io.IOException; @@ -48,7 +44,7 @@ public class MapJarsTiny { String toM = "pomf"; Path mappings = Constants.MAPPINGS_TINY.get(extension).toPath(); - Path[] classpath = task.getProject().getConfigurations().getByName(Constants.CONFIG_MC_DEPENDENCIES).getFiles().stream() + Path[] classpath = task.getProject().getConfigurations().getByName(Constants.CONFIG_MINECRAFT).getFiles().stream() .map(File::toPath) .toArray(Path[]::new); diff --git a/src/main/java/net/fabricmc/loom/task/RunClientTask.java b/src/main/java/net/fabricmc/loom/task/RunClientTask.java index ce76f51..9c760f4 100644 --- a/src/main/java/net/fabricmc/loom/task/RunClientTask.java +++ b/src/main/java/net/fabricmc/loom/task/RunClientTask.java @@ -79,7 +79,7 @@ public class RunClientTask extends JavaExec { @Override public String getMain() { - return "cpw.mods.modlauncher.Launcher"; + return "net.minecraft.launchwrapper.Launch"; } @Override diff --git a/src/main/java/net/fabricmc/loom/task/SetupTask.java b/src/main/java/net/fabricmc/loom/task/SetupTask.java new file mode 100644 index 0000000..9e25e38 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/task/SetupTask.java @@ -0,0 +1,61 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.task; + +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.util.Constants; +import net.fabricmc.loom.util.ModProccessor; +import org.apache.commons.lang3.Validate; +import org.gradle.api.DefaultTask; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.tasks.TaskAction; + +import java.io.File; + +public class SetupTask extends DefaultTask { + + @TaskAction + public void setup(){ + configureModRemapper(); + } + + public void configureModRemapper(){ + LoomGradleExtension extension = getProject().getExtensions().getByType(LoomGradleExtension.class); + Configuration inputConfig = getProject().getConfigurations().getByName(Constants.COMPILE_MODS); + inputConfig.getResolvedConfiguration().getFiles().stream() + .filter(file -> file.getName().endsWith(".jar")) + .forEach(input -> { + String outputName = input.getName().substring(0, input.getName().length() - 4) + "-mapped-" + extension.pomfVersion + ".jar";//TODO use the hash of the input file or something? + File output = new File(Constants.REMAPPED_MODS_STORE.get(extension), outputName); + if(!output.getParentFile().exists()){ + output.mkdirs(); + } + getProject().getLogger().lifecycle(":remapping jar " + input.getName()); + ModProccessor.handleMod(input, output, getProject()); + Validate.isTrue(output.exists()); + getProject().getDependencies().add(Constants.COMPILE_MODS_PROCESSED, getProject().files(output.getPath())); + }); + } +} diff --git a/src/main/java/net/fabricmc/loom/util/Constants.java b/src/main/java/net/fabricmc/loom/util/Constants.java index 8d6d001..5555a29 100644 --- a/src/main/java/net/fabricmc/loom/util/Constants.java +++ b/src/main/java/net/fabricmc/loom/util/Constants.java @@ -58,6 +58,8 @@ public class Constants { public static final IDelayed MAPPINGS_ENIGMA_ZIP_LOCAL = new DelayedFile(extension -> new File(MAPPINGS_DIR_LOCAL.get(extension), "pomf-enigma-" + extension.version + ".zip")); public static final IDelayed MAPPINGS_TINY_GZ_LOCAL = new DelayedFile(extension -> new File(MAPPINGS_DIR_LOCAL.get(extension), "pomf-tiny-" + extension.version + ".gz")); + public static final IDelayed REMAPPED_MODS_STORE = new DelayedFile(extension -> new File(CACHE_FILES, "remapped_mods")); + public static final IDelayed MINECRAFT_LIBS = new DelayedFile(extension -> new File(extension.getUserCache(), extension.version + "-libs")); public static final IDelayed MINECRAFT_NATIVES = new DelayedFile(extension -> new File(extension.getUserCache(), extension.version + "-natives")); public static final IDelayed MINECRAFT_JSON = new DelayedFile(extension -> new File(extension.getUserCache(), extension.version + "-info.json")); @@ -78,9 +80,9 @@ public class Constants { public static final String CONFIG_MC_DEPENDENCIES = "MC_DEPENDENCIES"; public static final String CONFIG_MINECRAFT = "MINECRAFT"; public static final String CONFIG_MC_DEPENDENCIES_CLIENT = "MC_DEPENDENCIES_CLIENT"; - public static final String PROCESS_MODS_DEPENDENCIES = "PROCESS_MODS_DEPENDENCIES"; public static final String SYSTEM_ARCH = System.getProperty("os.arch").equals("64") ? "64" : "32"; public static final String COMPILE_MODS = "modCompile"; + public static final String COMPILE_MODS_PROCESSED = "modCompile_PROCESSED"; public static List getClassPath() { URL[] urls = ((URLClassLoader) Constants.class.getClassLoader()).getURLs(); diff --git a/src/main/java/net/fabricmc/loom/util/ModProccessor.java b/src/main/java/net/fabricmc/loom/util/ModProccessor.java new file mode 100644 index 0000000..880c1dc --- /dev/null +++ b/src/main/java/net/fabricmc/loom/util/ModProccessor.java @@ -0,0 +1,129 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.util; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.tinyremapper.OutputConsumerPath; +import net.fabricmc.tinyremapper.TinyRemapper; +import net.fabricmc.tinyremapper.TinyUtils; +import org.apache.commons.io.IOUtils; +import org.gradle.api.Project; +import org.gradle.api.artifacts.dsl.DependencyHandler; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.jar.JarFile; +import java.util.zip.ZipEntry; + +public class ModProccessor { + + public static void handleMod(File input, File output, Project project){ + if(output.exists()){ + output.delete(); + } + remapJar(input, output, project); + + JsonObject jsonObject = readInstallerJson(input); + if(jsonObject != null){ + handleInstallerJson(jsonObject, project); + } + } + + private static void remapJar(File input, File output, Project project){ + LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); + String fromM = "mojang"; + String toM = "pomf"; + + Path mappings = Constants.MAPPINGS_TINY.get(extension).toPath(); + Path[] classpath = project.getConfigurations().getByName(Constants.CONFIG_MC_DEPENDENCIES).getFiles().stream() + .map(File::toPath) + .toArray(Path[]::new); + + project.getLogger().lifecycle(":remapping " + input.getName() + " (TinyRemapper, " + fromM + " -> " + toM + ")"); + + TinyRemapper remapper = TinyRemapper.newRemapper() + .withMappings(TinyUtils.createTinyMappingProvider(mappings, fromM, toM)) + .build(); + + try { + OutputConsumerPath outputConsumer = new OutputConsumerPath(Paths.get(output.getAbsolutePath())); + outputConsumer.addNonClassFiles(input.toPath()); + remapper.read(input.toPath()); + remapper.read(classpath); + remapper.apply(input.toPath(), outputConsumer); + outputConsumer.finish(); + remapper.finish(); + } catch (Exception e){ + remapper.finish(); + throw new RuntimeException("Failed to remap jar to " + toM, e); + } + if(!output.exists()){ + throw new RuntimeException("Failed to remap jar to " + toM + " file not found: " + output.getAbsolutePath()); + } + } + + private static void handleInstallerJson(JsonObject jsonObject, Project project){ + DependencyHandler dependencyHandler = project.getDependencies(); + + JsonObject libraries = jsonObject.get("libraries").getAsJsonObject(); + libraries.get("common").getAsJsonArray().forEach(jsonElement -> { + String name = jsonElement.getAsJsonObject().get("name").getAsString(); + dependencyHandler.add("compile", name); + + //TODO is it an issue if we add the same url twice? or do I need to check this? + if(jsonElement.getAsJsonObject().has("url")){ + project.getRepositories().maven(mavenArtifactRepository -> mavenArtifactRepository.setUrl(jsonElement.getAsJsonObject().get("url").getAsString())); + } + + }); + } + + private static JsonObject readInstallerJson(File file){ + try { + JarFile jarFile = new JarFile(file); + ZipEntry entry = jarFile.getEntry("fabric-installer.json"); + if(entry == null){ + return null; + } + InputStream inputstream = jarFile.getInputStream(entry); + String jsonStr = IOUtils.toString(inputstream, StandardCharsets.UTF_8); + inputstream.close(); + jarFile.close(); + + JsonObject jsonObject = new Gson().fromJson(jsonStr, JsonObject.class); + return jsonObject; + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + +}