diff --git a/build.gradle b/build.gradle index 89f8e5e..4e6261c 100644 --- a/build.gradle +++ b/build.gradle @@ -39,17 +39,14 @@ dependencies { implementation ('com.google.guava:guava:28.0-jre') // game handling utils - implementation ('net.fabricmc:stitch:0.3.0.66') { + implementation ('net.fabricmc:stitch:0.4.0.67') { exclude module: 'enigma' } // tinyfile management - implementation ('net.fabricmc:tiny-remapper:0.2.0.53') { + implementation ('net.fabricmc:tiny-remapper:0.2.0.56') { transitive = false } - implementation ('net.fabricmc:fabric-mixin-compile-extensions:0.2.0.3'){ - exclude group :"net.fabricmc" - } // decompilers implementation ('net.fabricmc:procyon-fabric-compilertools:0.5.35.+') diff --git a/src/main/java/net/fabricmc/loom/AbstractPlugin.java b/src/main/java/net/fabricmc/loom/AbstractPlugin.java index 88e135a..4b5ed44 100644 --- a/src/main/java/net/fabricmc/loom/AbstractPlugin.java +++ b/src/main/java/net/fabricmc/loom/AbstractPlugin.java @@ -30,7 +30,6 @@ 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; @@ -40,10 +39,7 @@ import org.gradle.api.Task; import org.gradle.api.UnknownTaskException; import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.Dependency; -import org.gradle.api.artifacts.component.ModuleComponentIdentifier; import org.gradle.api.artifacts.repositories.MavenArtifactRepository; -import org.gradle.api.artifacts.result.DependencyResult; -import org.gradle.api.artifacts.result.ResolvedDependencyResult; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPluginConvention; import org.gradle.api.publish.Publication; @@ -57,6 +53,7 @@ import org.gradle.api.tasks.scala.ScalaCompile; import org.gradle.plugins.ide.eclipse.model.EclipseModel; import org.gradle.plugins.ide.idea.model.IdeaModel; +import net.fabricmc.loom.providers.LaunchProvider; import net.fabricmc.loom.providers.MappingsProvider; import net.fabricmc.loom.providers.MinecraftProvider; import net.fabricmc.loom.task.RemapJarTask; @@ -199,8 +196,8 @@ public class AbstractPlugin implements Plugin { * 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) { @@ -226,42 +223,6 @@ public class AbstractPlugin implements Plugin { EclipseModel eclipseModel = (EclipseModel) project.getExtensions().getByName("eclipse"); } - private void addModule(Project proj, String configuration, DependencyResult module) { - if (module instanceof ResolvedDependencyResult) { - if (module.getFrom().getId() instanceof ModuleComponentIdentifier) { - ModuleComponentIdentifier mci = ((ModuleComponentIdentifier) module.getFrom().getId()); - String moduleId = mci.getGroup() + ":" + mci.getModule() + ":" + mci.getVersion(); - proj.getDependencies().add(configuration, proj.getDependencies().module(moduleId)); - proj.getLogger().debug("Loom addModule " + moduleId + " to " + configuration); - } - - for (DependencyResult child : ((ResolvedDependencyResult) module).getSelected().getDependencies()) { - addModule(proj, configuration, child); - } - } - } - - private boolean findAndAddModule(Project project, String configuration, DependencyResult dep, Predicate predicate) { - boolean found = false; - - 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; - } - } - - for (DependencyResult child : ((ResolvedDependencyResult) dep).getSelected().getDependencies()) { - findAndAddModule(project, configuration, child, predicate); - } - } - - return found; - } - /** * Add Minecraft dependencies to compile time. */ @@ -275,21 +236,7 @@ public class AbstractPlugin implements Plugin { javadoc.setClasspath(main.getOutput().plus(main.getCompileClasspath())); // 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; - } - - p = p.getRootProject(); - } + project.getDependencies().add(JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME, "net.fabricmc:fabric-mixin-compile-extensions:" + Constants.MIXIN_COMPILE_EXTENSIONS_VERSION); project.afterEvaluate(project1 -> { LoomGradleExtension extension = project1.getExtensions().getByType(LoomGradleExtension.class); @@ -332,6 +279,7 @@ public class AbstractPlugin implements Plugin { dependencyManager.addProvider(new MinecraftProvider()); dependencyManager.addProvider(new MappingsProvider()); + dependencyManager.addProvider(new LaunchProvider()); dependencyManager.handleDependencies(project1); diff --git a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java index 15abb2a..959f573 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java +++ b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java @@ -175,6 +175,10 @@ public class LoomGradleExtension { return natives; } + public File getDevLauncherConfig() { + return new File(getRootProjectPersistentCache(), "launch.cfg"); + } + @Nullable private static Dependency findDependency(Project p, Collection configs, BiPredicate groupNameFilter) { for (Configuration config : configs) { diff --git a/src/main/java/net/fabricmc/loom/providers/LaunchProvider.java b/src/main/java/net/fabricmc/loom/providers/LaunchProvider.java new file mode 100644 index 0000000..65a9825 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/providers/LaunchProvider.java @@ -0,0 +1,105 @@ +/* + * 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.providers; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.StringJoiner; +import java.util.function.Consumer; + +import org.apache.commons.io.FileUtils; +import org.gradle.api.Project; + +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.util.Constants; +import net.fabricmc.loom.util.DependencyProvider; + +public class LaunchProvider extends DependencyProvider { + @Override + public void provide(DependencyInfo dependency, Project project, LoomGradleExtension extension, Consumer postPopulationScheduler) throws IOException { + final LaunchConfig launchConfig = new LaunchConfig() + .property("fabric.development", "true") + + .property("client", "java.library.path", extension.getNativesDirectory().getAbsolutePath()) + .property("client", "org.lwjgl.librarypath", extension.getNativesDirectory().getAbsolutePath()) + + .argument("client", "--assetIndex") + .argument("client", extension.getMinecraftProvider().versionInfo.assetIndex.getFabricId(extension.getMinecraftProvider().minecraftVersion)) + .argument("client", "--assetsDir") + .argument("client", new File(extension.getUserCache(), "assets").getAbsolutePath()); + + FileUtils.writeStringToFile(extension.getDevLauncherConfig(), launchConfig.asString(), StandardCharsets.UTF_8); + + addDependency("net.fabricmc:dev-launch-injector:" + Constants.DEV_LAUNCH_INJECTOR_VERSION, project, "runtimeOnly"); + } + + @Override + public String getTargetConfig() { + return Constants.MINECRAFT_NAMED; + } + + public static class LaunchConfig { + private final Map> values = new HashMap<>(); + + public LaunchConfig property(String key, String value) { + return property("common", key, value); + } + + public LaunchConfig property(String side, String key, String value) { + values.computeIfAbsent(side + "Properties", (s -> new ArrayList<>())) + .add(String.format("%s=%s", key, value)); + return this; + } + + public LaunchConfig argument(String value) { + return argument("common", value); + } + + public LaunchConfig argument(String side, String value) { + values.computeIfAbsent(side + "Args", (s -> new ArrayList<>())) + .add(value); + return this; + } + + public String asString() { + StringJoiner stringJoiner = new StringJoiner("\n"); + + for (Map.Entry> entry : values.entrySet()) { + stringJoiner.add(entry.getKey()); + + for (String s : entry.getValue()) { + stringJoiner.add("\t" + s); + } + } + + return stringJoiner.toString(); + } + } +} diff --git a/src/main/java/net/fabricmc/loom/task/GenEclipseRunsTask.java b/src/main/java/net/fabricmc/loom/task/GenEclipseRunsTask.java index 546457c..874e986 100644 --- a/src/main/java/net/fabricmc/loom/task/GenEclipseRunsTask.java +++ b/src/main/java/net/fabricmc/loom/task/GenEclipseRunsTask.java @@ -43,11 +43,11 @@ public class GenEclipseRunsTask extends AbstractLoomTask { 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()) { + if (!clientRunConfigs.exists() || RunConfig.needsUpgrade(clientRunConfigs)) { FileUtils.writeStringToFile(clientRunConfigs, clientRunConfig, StandardCharsets.UTF_8); } - if (!serverRunConfigs.exists()) { + if (!serverRunConfigs.exists() || RunConfig.needsUpgrade(serverRunConfigs)) { FileUtils.writeStringToFile(serverRunConfigs, serverRunConfig, StandardCharsets.UTF_8); } diff --git a/src/main/java/net/fabricmc/loom/util/Constants.java b/src/main/java/net/fabricmc/loom/util/Constants.java index 26aa4ff..4999d7d 100644 --- a/src/main/java/net/fabricmc/loom/util/Constants.java +++ b/src/main/java/net/fabricmc/loom/util/Constants.java @@ -39,9 +39,13 @@ 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"; @@ -51,4 +55,7 @@ public class Constants { public static final String MINECRAFT_LINEMAPPED = "minecraftLinemapped"; public static final String MAPPINGS = "mappings"; public static final String MAPPINGS_FINAL = "mappingsFinal"; + + public static final String MIXIN_COMPILE_EXTENSIONS_VERSION = "0.2.0.3"; + public static final String DEV_LAUNCH_INJECTOR_VERSION = "0.1.0+build.3"; } diff --git a/src/main/java/net/fabricmc/loom/util/ModProcessor.java b/src/main/java/net/fabricmc/loom/util/ModProcessor.java index 03cf2e0..a7b9367 100644 --- a/src/main/java/net/fabricmc/loom/util/ModProcessor.java +++ b/src/main/java/net/fabricmc/loom/util/ModProcessor.java @@ -165,6 +165,7 @@ public class ModProcessor { TinyRemapper remapper = TinyRemapper.newRemapper() .withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM, false)) + .renameInvalidLocals(true) .build(); try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(Paths.get(output.getAbsolutePath())).build()) { diff --git a/src/main/java/net/fabricmc/loom/util/RunConfig.java b/src/main/java/net/fabricmc/loom/util/RunConfig.java index 2b52459..ee66495 100644 --- a/src/main/java/net/fabricmc/loom/util/RunConfig.java +++ b/src/main/java/net/fabricmc/loom/util/RunConfig.java @@ -29,7 +29,6 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.List; -import java.util.Locale; import java.util.Map; import javax.xml.parsers.ParserConfigurationException; @@ -40,6 +39,7 @@ 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.FileUtils; import org.apache.commons.io.IOUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -96,7 +96,7 @@ 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 = ""; switch (extension.getLoaderLaunchMethod()) { case "launchwrapper": @@ -104,52 +104,37 @@ public class RunConfig { 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.mainClass = "net.fabricmc.devlaunchinjector.Main"; runConfig.programArgs = ""; + runConfig.vmArgs = "-Dfabric.dli.config=\"" + extension.getDevLauncherConfig().getAbsolutePath() + "\" -Dfabric.dli.env=" + mode.toLowerCase(); break; } - // if installer.json found... - JsonObject installerJson = extension.getInstallerJson(); + if (extension.getLoaderLaunchMethod().equals("launchwrapper")) { + // if installer.json found... + JsonObject installerJson = extension.getInstallerJson(); - if (installerJson != null) { - List sideKeys = ImmutableList.of(mode, "common"); + if (installerJson != null) { + List sideKeys = ImmutableList.of(mode, "common"); - // copy main class - if (installerJson.has("mainClass")) { - JsonElement mainClassJson = installerJson.get("mainClass"); + // copy launchwrapper tweakers + if (installerJson.has("launchwrapper")) { + JsonObject launchwrapperJson = installerJson.getAsJsonObject("launchwrapper"); - if (mainClassJson.isJsonObject()) { - JsonObject mainClassesJson = mainClassJson.getAsJsonObject(); + if (launchwrapperJson.has("tweakers")) { + JsonObject tweakersJson = launchwrapperJson.getAsJsonObject("tweakers"); + StringBuilder builder = new StringBuilder(); - for (String s : sideKeys) { - if (mainClassesJson.has(s)) { - runConfig.mainClass = mainClassesJson.get(s).getAsString(); - break; - } - } - } else { - runConfig.mainClass = mainClassJson.getAsString(); - } - } - - // 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)) { - builder.append(" --tweakClass ").append(element.getAsString()); + for (String s : sideKeys) { + if (tweakersJson.has(s)) { + for (JsonElement element : tweakersJson.getAsJsonArray(s)) { + builder.append(" --tweakClass ").append(element.getAsString()); + } } } - } - runConfig.programArgs += builder.toString(); + runConfig.programArgs += builder.toString(); + } } } } @@ -163,8 +148,8 @@ public class RunConfig { RunConfig ideaClient = new RunConfig(); populate(project, extension, ideaClient, "client"); ideaClient.configName = "Minecraft Client"; - ideaClient.programArgs += " --assetIndex \"" + minecraftVersionInfo.assetIndex.getFabricId(extension.getMinecraftProvider().minecraftVersion) + "\" --assetsDir \"" + new File(extension.getUserCache(), "assets").getAbsolutePath() + "\""; ideaClient.vmArgs += getOSClientJVMArgs(); + ideaClient.vmArgs += " -Dfabric.dli.main=" + getMainClass("client", extension); return ideaClient; } @@ -175,10 +160,17 @@ public class RunConfig { RunConfig ideaServer = new RunConfig(); populate(project, extension, ideaServer, "server"); ideaServer.configName = "Minecraft Server"; + ideaServer.vmArgs += " -Dfabric.dli.main=" + getMainClass("server", extension); return ideaServer; } + //This can be removed at somepoint, its not ideal but its the best solution I could thing of + public static boolean needsUpgrade(File file) throws IOException { + String contents = FileUtils.readFileToString(file, StandardCharsets.UTF_8); + return !(contents.contains("net.fabricmc.devlaunchinjector.Main")); + } + public String fromDummy(String dummy) throws IOException { String dummyConfig; @@ -202,4 +194,28 @@ public class RunConfig { return ""; } + + private static String getMainClass(String side, LoomGradleExtension extension) { + JsonObject installerJson = extension.getInstallerJson(); + + if (installerJson != null && installerJson.has("mainClass")) { + JsonElement mainClassJson = installerJson.get("mainClass"); + + String mainClassName = ""; + + if (mainClassJson.isJsonObject()) { + JsonObject mainClassesJson = mainClassJson.getAsJsonObject(); + + if (mainClassesJson.has(side)) { + mainClassName = mainClassesJson.get(side).getAsString(); + } + } else { + mainClassName = mainClassJson.getAsString(); + } + + return mainClassName; + } + + throw new RuntimeException("Failed to find mainclass"); + } } diff --git a/src/main/java/net/fabricmc/loom/util/SetupIntelijRunConfigs.java b/src/main/java/net/fabricmc/loom/util/SetupIntelijRunConfigs.java index f408b5f..018eb0c 100644 --- a/src/main/java/net/fabricmc/loom/util/SetupIntelijRunConfigs.java +++ b/src/main/java/net/fabricmc/loom/util/SetupIntelijRunConfigs.java @@ -78,11 +78,11 @@ public class SetupIntelijRunConfigs { 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() || RunConfig.needsUpgrade(clientRunConfigs)) { FileUtils.writeStringToFile(clientRunConfigs, clientRunConfig, StandardCharsets.UTF_8); } - if (!serverRunConfigs.exists()) { + if (!serverRunConfigs.exists() || RunConfig.needsUpgrade(serverRunConfigs)) { FileUtils.writeStringToFile(serverRunConfigs, serverRunConfig, StandardCharsets.UTF_8); } }