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
This commit is contained in:
parent
2bd339241f
commit
f85daec559
59 changed files with 2129 additions and 1655 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -17,4 +17,6 @@
|
|||
!/LICENSE
|
||||
!/README.md
|
||||
!/settings.gradle
|
||||
!/Jenkinsfile
|
||||
!/Jenkinsfile
|
||||
!/.travis.yml
|
||||
!/checkstyle.xml
|
12
.travis.yml
Normal file
12
.travis.yml
Normal file
|
@ -0,0 +1,12 @@
|
|||
language: java
|
||||
install: true
|
||||
|
||||
jdk:
|
||||
- openjdk8
|
||||
|
||||
script:
|
||||
- chmod +x gradlew
|
||||
- ./gradlew check build test --stacktrace
|
||||
|
||||
notifications:
|
||||
email: false
|
16
build.gradle
16
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 {
|
||||
|
|
162
checkstyle.xml
Normal file
162
checkstyle.xml
Normal file
|
@ -0,0 +1,162 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.2//EN" "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
|
||||
<module name="Checker">
|
||||
<property name="charset" value="UTF-8"/>
|
||||
<property name="fileExtensions" value="java"/>
|
||||
|
||||
<module name="NewlineAtEndOfFile"/>
|
||||
|
||||
<!-- disallow trailing whitespace -->
|
||||
<module name="RegexpSingleline">
|
||||
<property name="format" value="\s+$"/>
|
||||
<property name="message" value="trailing whitespace"/>
|
||||
</module>
|
||||
|
||||
<!-- note: RegexpMultiline shows nicer messages than Regexp, but has to be outside TreeWalker -->
|
||||
<!-- disallow multiple consecutive blank lines -->
|
||||
<module name="RegexpMultiline">
|
||||
<property name="format" value="\n[\r\t ]*\n[\r\t ]*\n"/>
|
||||
<property name="message" value="adjacent blank lines"/>
|
||||
</module>
|
||||
|
||||
<!-- disallow blank after { -->
|
||||
<module name="RegexpMultiline">
|
||||
<property name="format" value="\{[\r\t ]*\n[\r\t ]*\n"/>
|
||||
<property name="message" value="blank line after '{'"/>
|
||||
</module>
|
||||
|
||||
<!-- disallow blank before } -->
|
||||
<module name="RegexpMultiline">
|
||||
<property name="format" value="\n[\r\t ]*\n[\r\t ]*\}"/>
|
||||
<property name="message" value="blank line before '}'"/>
|
||||
</module>
|
||||
|
||||
<!-- require blank before { in the same indentation level -->
|
||||
<module name="RegexpMultiline">
|
||||
<!-- the regex works as follows:
|
||||
It matches (=fails) for \n<indentation><something>\n<same indentation><control statement>[...]{\n
|
||||
while <something> is a single line comment, it'll look for a blank line one line earlier
|
||||
if <something> is a space, indicating a formatting error or ' */', it'll ignore the instance
|
||||
if <something> is a tab, indicating a continued line, it'll ignore the instance
|
||||
<control statement> is 'if', 'do', 'while', 'for', 'try' or nothing (instance initializer block)
|
||||
|
||||
- first \n: with positive lookbehind (?<=\n) to move the error marker to a more reasonable place
|
||||
- capture tabs for <indentation>, later referenced via \1
|
||||
- remaining preceding line as a non-comment (doesn't start with '/', '//', ' ' or '\t') or multiple lines where all but the first are a single line comment with the same indentation
|
||||
- new line
|
||||
- <indentation> as captured earlier
|
||||
- <control statement> as specified above
|
||||
- { before the next new line -->
|
||||
<property name="format" value="(?<=\n)([\t]+)(?:[^/\n \t][^\n]*|/[^/\n][^\n]*|[^/\n][^\n]*(\n\1//[^\n]*)+)\n\1(|(if|do|while|for|try)[^\n]+)\{[\r\t ]*\n"/>
|
||||
<property name="message" value="missing blank line before block at same indentation level"/>
|
||||
</module>
|
||||
|
||||
<!-- require blank after } in the same indentation level -->
|
||||
<module name="RegexpMultiline">
|
||||
<!-- \n<indentation>}\n<same indentation><whatever unless newline, '}' or starting with cas(e) or def(ault)> -->
|
||||
<property name="format" value="(?<=\n)([\t]+)\}\n\1(?:[^\r\n\}cd]|c[^\r\na]|ca[^\r\ns]|d[^\r\ne]|de[^\r\nf])"/>
|
||||
<property name="message" value="missing blank line after block at same indentation level"/>
|
||||
</module>
|
||||
|
||||
<module name="TreeWalker">
|
||||
<!-- Ensure all imports are ship shape -->
|
||||
<module name="AvoidStarImport"/>
|
||||
<module name="IllegalImport"/>
|
||||
<module name="RedundantImport"/>
|
||||
<module name="UnusedImports"/>
|
||||
|
||||
<module name="ImportOrder">
|
||||
<property name="groups" value="java,javax,*,net.minecraft,net.fabricmc"/>
|
||||
<property name="ordered" value="false"/><!-- the plugin orders alphabetically without considering separators.. -->
|
||||
<property name="separated" value="true"/>
|
||||
<property name="option" value="top"/>
|
||||
<property name="sortStaticImportsAlphabetically" value="true"/>
|
||||
</module>
|
||||
|
||||
<!-- Ensures braces are at the end of a line -->
|
||||
<module name="LeftCurly"/>
|
||||
<module name="RightCurly"/>
|
||||
|
||||
<!-- single line statements on one line, -->
|
||||
<module name="NeedBraces">
|
||||
<property name="tokens" value="LITERAL_IF,LITERAL_FOR,LITERAL_WHILE"/>
|
||||
<property name="allowSingleLineStatement" value="true"/>
|
||||
</module>
|
||||
<module name="NeedBraces">
|
||||
<property name="tokens" value="LITERAL_ELSE,LITERAL_DO"/>
|
||||
<property name="allowSingleLineStatement" value="false"/>
|
||||
</module>
|
||||
|
||||
<module name="EmptyLineSeparator">
|
||||
<property name="allowNoEmptyLineBetweenFields" value="true"/>
|
||||
<property name="allowMultipleEmptyLines" value="false"/>
|
||||
<!-- exclude METHOD_DEF and VARIABLE_DEF -->
|
||||
<property name="tokens" value="PACKAGE_DEF,IMPORT,STATIC_IMPORT,CLASS_DEF,INTERFACE_DEF,ENUM_DEF,STATIC_INIT,INSTANCE_INIT,CTOR_DEF"/>
|
||||
</module>
|
||||
|
||||
<module name="OperatorWrap"/>
|
||||
<module name="SeparatorWrap">
|
||||
<property name="tokens" value="DOT,ELLIPSIS,AT"/>
|
||||
<property name="option" value="nl"/>
|
||||
</module>
|
||||
<module name="SeparatorWrap">
|
||||
<property name="tokens" value="COMMA,SEMI"/>
|
||||
<property name="option" value="eol"/>
|
||||
</module>
|
||||
|
||||
<module name="Indentation">
|
||||
<property name="basicOffset" value="8"/>
|
||||
<property name="caseIndent" value="0"/>
|
||||
<property name="throwsIndent" value="8"/>
|
||||
<property name="arrayInitIndent" value="8"/>
|
||||
<property name="lineWrappingIndentation" value="16"/>
|
||||
</module>
|
||||
|
||||
<module name="ParenPad"/>
|
||||
<module name="NoWhitespaceBefore"/>
|
||||
<module name="NoWhitespaceAfter">
|
||||
<!-- allow ARRAY_INIT -->
|
||||
<property name="tokens" value="AT,INC,DEC,UNARY_MINUS,UNARY_PLUS,BNOT,LNOT,DOT,ARRAY_DECLARATOR,INDEX_OP"/>
|
||||
</module>
|
||||
<module name="WhitespaceAfter"/>
|
||||
<module name="WhitespaceAround">
|
||||
<!-- Allow PLUS, MINUS, MUL, DIV as they may be more readable without spaces in some cases -->
|
||||
<property name="tokens" value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN,BXOR,BXOR_ASSIGN,COLON,DIV_ASSIGN,DO_WHILE,EQUAL,GE,GT,LAMBDA,LAND,LCURLY,LE,LITERAL_CATCH,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_RETURN,LITERAL_SWITCH,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE,LOR,LT,MINUS_ASSIGN,MOD,MOD_ASSIGN,NOT_EQUAL,PLUS_ASSIGN,QUESTION,RCURLY,SL,SLIST,SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN,LITERAL_ASSERT,TYPE_EXTENSION_AND"/>
|
||||
</module>
|
||||
<module name="SingleSpaceSeparator"/>
|
||||
<module name="GenericWhitespace"/>
|
||||
<module name="CommentsIndentation"/>
|
||||
|
||||
<module name="ArrayTypeStyle"/>
|
||||
<module name="DefaultComesLast">
|
||||
<property name="skipIfLastAndSharedWithCase" value="true"/>
|
||||
</module>
|
||||
<module name="SimplifyBooleanExpression"/>
|
||||
<module name="SimplifyBooleanReturn"/>
|
||||
<module name="StringLiteralEquality"/>
|
||||
|
||||
<module name="ModifierOrder"/>
|
||||
<module name="RedundantModifier"/>
|
||||
|
||||
<module name="AnnotationLocation"/>
|
||||
<module name="MissingOverride"/>
|
||||
|
||||
<!-- By default this allows catch blocks with only comments -->
|
||||
<module name="EmptyCatchBlock"/>
|
||||
|
||||
<!-- Enforce tabs -->
|
||||
<module name="RegexpSinglelineJava">
|
||||
<property name="format" value="^\t* ([^*]|\*[^ /])"/>
|
||||
<property name="message" value="non-tab indentation"/>
|
||||
</module>
|
||||
|
||||
<module name="OuterTypeFilename"/>
|
||||
|
||||
<!--<module name="InvalidJavadocPosition"/>-->
|
||||
<module name="JavadocParagraph"/>
|
||||
<module name="JavadocStyle"/>
|
||||
<module name="AtclauseOrder">
|
||||
<property name="tagOrder" value="@param,@return,@throws,@deprecated"/>
|
||||
</module>
|
||||
</module>
|
||||
</module>
|
|
@ -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<Project> {
|
||||
protected Project project;
|
||||
|
@ -116,6 +122,7 @@ public class AbstractPlugin implements Plugin<Project> {
|
|||
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<Project> {
|
|||
configureScala();
|
||||
|
||||
Map<Project, Set<Task>> taskMap = project.getAllTasks(true);
|
||||
|
||||
for (Map.Entry<Project, Set<Task>> entry : taskMap.entrySet()) {
|
||||
Project project = entry.getKey();
|
||||
Set<Task> 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<Project> {
|
|||
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<Project> {
|
|||
}
|
||||
|
||||
/**
|
||||
* 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<Project> {
|
|||
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<Project> {
|
|||
}
|
||||
|
||||
/**
|
||||
* 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<Project> {
|
|||
|
||||
// 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<Project> {
|
|||
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<Project> {
|
|||
project1.getTasks().getByName("build").dependsOn(remapJarTask);
|
||||
|
||||
Map<Project, Set<Task>> taskMap = project.getAllTasks(true);
|
||||
|
||||
for (Map.Entry<Project, Set<Task>> entry : taskMap.entrySet()) {
|
||||
Set<Task> 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<Project> {
|
|||
|
||||
// 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<Project> {
|
|||
Node dependencies = GroovyXmlUtil.getOrCreateNode(xml.asNode(), "dependencies");
|
||||
Set<String> foundArtifacts = new HashSet<>();
|
||||
|
||||
GroovyXmlUtil.childrenNodesStream(dependencies)
|
||||
.filter((n) -> "dependency".equals(n.name()))
|
||||
.forEach((n) -> {
|
||||
Optional<Node> groupId = GroovyXmlUtil.getNode(n, "groupId");
|
||||
Optional<Node> 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<Node> groupId = GroovyXmlUtil.getNode(n, "groupId");
|
||||
Optional<Node> 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())) {
|
||||
|
|
|
@ -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> T recurseProjects(Function<Project, T> 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<Configuration> 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";
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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<Path, SoftReference<Mappings>> mappingsCache = new HashMap<>();
|
||||
private final Map<Path, SoftReference<Mappings>> 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<Mappings> 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<Mappings> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<String, AssetObject> parent = index.getFileMap();
|
||||
final int totalSize = parent.size();
|
||||
int position = 0;
|
||||
project.getLogger().lifecycle(":downloading assets...");
|
||||
|
||||
for (Map.Entry<String, AssetObject> 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++;
|
||||
}
|
||||
|
|
|
@ -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<File> 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");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<Runnable> 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<Runnable> 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<File> 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<File> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<ManifestVersion.Versions> 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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,9 +27,7 @@ package net.fabricmc.loom.task;
|
|||
import org.gradle.api.DefaultTask;
|
||||
|
||||
public abstract class AbstractLoomTask extends DefaultTask {
|
||||
|
||||
public AbstractLoomTask() {
|
||||
setGroup("fabric");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<Project, RunConfig> configProvider;
|
||||
private RunConfig config;
|
||||
private final Function<Project, RunConfig> configProvider;
|
||||
private RunConfig config;
|
||||
|
||||
public AbstractRunTask(Function<Project, RunConfig> config) {
|
||||
super();
|
||||
setGroup("fabric");
|
||||
this.configProvider = config;
|
||||
}
|
||||
public AbstractRunTask(Function<Project, RunConfig> 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<String> 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<String> libs = new ArrayList<>();
|
||||
|
||||
classpath(libs);
|
||||
List<String> 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<String> 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<String> getJvmArgs() {
|
||||
if (config == null) {
|
||||
config = configProvider.apply(getProject());
|
||||
}
|
||||
|
||||
LoomGradleExtension extension = this.getProject().getExtensions().getByType(LoomGradleExtension.class);
|
||||
List<String> superArgs = super.getJvmArgs();
|
||||
List<String> 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<String> getJvmArgs() {
|
||||
if (config == null) {
|
||||
config = configProvider.apply(getProject());
|
||||
}
|
||||
|
||||
LoomGradleExtension extension = this.getProject().getExtensions().getByType(LoomGradleExtension.class);
|
||||
List<String> superArgs = super.getJvmArgs();
|
||||
List<String> args = new ArrayList<>(superArgs != null ? superArgs : Collections.emptyList());
|
||||
args.addAll(Arrays.asList(config.vmArgs.split(" ")));
|
||||
return args;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
* <p>Created by covers1624 on 11/02/19.
|
||||
*/
|
||||
public interface ForkingJavaExecTask extends Task {
|
||||
default ExecResult javaexec(Action<? super JavaExecSpec> action) {
|
||||
ConfigurationContainer configurations = getProject().getBuildscript().getConfigurations();
|
||||
DependencyHandler handler = getProject().getDependencies();
|
||||
FileCollection classpath = configurations.getByName("classpath")//
|
||||
.plus(configurations.detachedConfiguration(handler.localGroovy()));
|
||||
|
||||
default ExecResult javaexec(Action<? super JavaExecSpec> 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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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<VsCodeConfiguration> 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<VsCodeConfiguration> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<String, ?> properties = project.getProperties();
|
||||
@TaskAction
|
||||
public void doTask() throws Throwable {
|
||||
Project project = getProject();
|
||||
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
|
||||
Map<String, ?> 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<String, ClassEntry> targetClasses = new HashMap<>();
|
||||
Map<EntryTriple, FieldEntry> targetFields = new HashMap<>();
|
||||
Map<EntryTriple, MethodEntry> 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<String, ClassEntry> targetClasses = new HashMap<>();
|
||||
Map<EntryTriple, FieldEntry> targetFields = new HashMap<>();
|
||||
Map<EntryTriple, MethodEntry> 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 { }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<String, Object> 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<String, Object> 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<String> args = new ArrayList<>();
|
||||
|
||||
List<String> 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<ProgressLogger> loggerFactory = () -> {
|
||||
ProgressLogger pl = factory.newOperation(getClass(), progressGroup);
|
||||
pl.setDescription("decompile worker");
|
||||
pl.started();
|
||||
return pl;
|
||||
};
|
||||
Stack<ProgressLogger> freeLoggers = new Stack<>();
|
||||
Map<String, ProgressLogger> 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<ProgressLogger> loggerFactory = () -> {
|
||||
ProgressLogger pl = factory.newOperation(getClass(), progressGroup);
|
||||
pl.setDescription("decompile worker");
|
||||
pl.started();
|
||||
return pl;
|
||||
};
|
||||
Stack<ProgressLogger> freeLoggers = new Stack<>();
|
||||
Map<String, ProgressLogger> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<String, Object> options = new HashMap<>();
|
||||
File input = null;
|
||||
File output = null;
|
||||
File lineMap = null;
|
||||
List<File> libraries = new ArrayList<>();
|
||||
int numThreads = 0;
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
Map<String, Object> options = new HashMap<>();
|
||||
File input = null;
|
||||
File output = null;
|
||||
File lineMap = null;
|
||||
List<File> 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<String, Object> options, List<File> 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<String, Object> options, List<File> 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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) { }
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
* <p>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<Stack<String>> workingClass = ThreadLocal.withInitial(Stack::new);
|
||||
private ThreadLocal<Stack<String>> line = ThreadLocal.withInitial(Stack::new);
|
||||
|
||||
private ThreadLocal<Stack<String>> workingClass = ThreadLocal.withInitial(Stack::new);
|
||||
private ThreadLocal<Stack<String>> 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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<File> output;
|
||||
private final Supplier<File> lineMapFile;
|
||||
private final Supplier<File> output;
|
||||
private final Supplier<File> lineMapFile;
|
||||
|
||||
public Map<String, ZipOutputStream> outputStreams = new HashMap<>();
|
||||
public Map<String, ExecutorService> saveExecutors = new HashMap<>();
|
||||
public PrintWriter lineMapWriter;
|
||||
public Map<String, ZipOutputStream> outputStreams = new HashMap<>();
|
||||
public Map<String, ExecutorService> saveExecutors = new HashMap<>();
|
||||
public PrintWriter lineMapWriter;
|
||||
|
||||
public ThreadSafeResultSaver(Supplier<File> output, Supplier<File> lineMapFile) {
|
||||
this.output = output;
|
||||
this.lineMapFile = lineMapFile;
|
||||
}
|
||||
public ThreadSafeResultSaver(Supplier<File> output, Supplier<File> 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) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<RemappedConfigurationEntry> 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<RemappedConfigurationEntry> 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";
|
||||
|
|
|
@ -32,33 +32,36 @@ import java.util.function.Consumer;
|
|||
* Created by covers1624 on 20/12/18.
|
||||
*/
|
||||
public class ConsumingOutputStream extends OutputStream {
|
||||
private final Consumer<String> consumer;
|
||||
|
||||
private final Consumer<String> consumer;
|
||||
private StringBuilder buffer = new StringBuilder();
|
||||
|
||||
private StringBuilder buffer = new StringBuilder();
|
||||
public ConsumingOutputStream(Consumer<String> consumer) {
|
||||
this.consumer = consumer;
|
||||
}
|
||||
|
||||
public ConsumingOutputStream(Consumer<String> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Runnable> 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<File> resolveFile() {
|
||||
Set<File> 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<File> 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
|
||||
|
|
|
@ -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 <code>true</code>) 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 <code>.etag</code> on the end of the name
|
||||
* Creates a new file in the same directory as the given file with <code>.etag</code> 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 <code>null</code> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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<String, RClass> lineMap = new HashMap<>();
|
||||
|
||||
private final Map<String, RClass> 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<Path>() {
|
||||
@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<Path>() {
|
||||
@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<Integer, Integer> 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<Integer, Integer> lineMap = new HashMap<>();
|
||||
|
||||
private RClass(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<DependencyProvider> 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> T getProvider(Class<T> clazz){
|
||||
for(DependencyProvider provider : dependencyProviderList){
|
||||
if(provider.getClass() == clazz){
|
||||
public <T> T getProvider(Class<T> 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<Runnable> afterTasks = new ArrayList<>();
|
||||
|
||||
MappingsProvider mappingsProvider = null;
|
||||
|
@ -80,7 +88,7 @@ public class LoomDependencyManager {
|
|||
Map<String, ProviderList> providerListMap = new HashMap<>();
|
||||
List<ProviderList> 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()));
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<Library> libraries;
|
||||
public Map<String, Downloads> 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<String> mixinFilenames = findMixins(output, true);
|
||||
|
||||
public static boolean addRefmapName(String filename, String mixinVersion, Path outputPath) {
|
||||
File output = outputPath.toFile();
|
||||
Set<String> 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<String> findMixins(File output, boolean onlyWithoutRefmap) {
|
||||
// first, identify all of the mixin files
|
||||
Set<String> 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<String> findMixins(File output, boolean onlyWithoutRefmap) {
|
||||
// first, identify all of the mixin files
|
||||
Set<String> 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<String> findRefmaps(File output) {
|
||||
// first, identify all of the mixin refmaps
|
||||
Set<String> 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<String> findRefmaps(File output) {
|
||||
// first, identify all of the mixin refmaps
|
||||
Set<String> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Runnable> 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Path> 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;
|
||||
}
|
||||
|
|
|
@ -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<RemapJarTask> getRequiredTasks(Project project){
|
||||
public static List<RemapJarTask> getRequiredTasks(Project project) {
|
||||
List<RemapJarTask> 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<File> prepareForNesting(Set<File> files, Dependency dependency, Project project){
|
||||
private static List<File> prepareForNesting(Set<File> files, Dependency dependency, Project project) {
|
||||
List<File> 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));
|
||||
|
|
|
@ -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")) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<String, String> values) {
|
||||
Document doc = parent.getOwnerDocument();
|
||||
|
||||
if (doc == null) {
|
||||
doc = (Document) parent;
|
||||
}
|
||||
|
||||
Element e = doc.createElement(name);
|
||||
|
||||
for (Map.Entry<String, String> 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<String> 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 "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 { }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<Path, Boolean> changeCache = new HashMap<>();
|
||||
private final WatchService service;
|
||||
private final Map<Path, WatchKey> pathsObserved = new HashMap<>();
|
||||
private final Map<Path, Boolean> changeCache = new HashMap<>();
|
||||
private final WatchService service;
|
||||
private final Map<Path, WatchKey> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) -> {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,4 +54,4 @@ public class AssetObject {
|
|||
result = 31 * result + (int) (this.size ^ this.size >>> 32);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
|||
}
|
||||
|
||||
/**
|
||||
* <p>Sets the description of the operation. This should be a full, stand-alone description of the operation.
|
||||
* <p>
|
||||
* <p>This must be called before {@link #started()}.
|
||||
* Sets the description of the operation. This should be a full, stand-alone description of the operation.
|
||||
*
|
||||
* <p>This must be called before {@link #started()}
|
||||
*
|
||||
* @param description The description.
|
||||
*/
|
||||
|
@ -143,8 +147,8 @@ public class ProgressLogger {
|
|||
}
|
||||
|
||||
/**
|
||||
* <p>Sets the short description of the operation. This is used in place of the full description when display space is limited.
|
||||
* <p>
|
||||
* Sets the short description of the operation. This is used in place of the full description when display space is limited.
|
||||
*
|
||||
* <p>This must be called before {@link #started()}
|
||||
*
|
||||
* @param description The short description.
|
||||
|
@ -155,9 +159,9 @@ public class ProgressLogger {
|
|||
}
|
||||
|
||||
/**
|
||||
* <p>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.
|
||||
* <p>
|
||||
*
|
||||
* <p>If not specified, no logging header is logged.
|
||||
*
|
||||
* @return The logging header, possibly empty.
|
||||
|
@ -167,7 +171,7 @@ public class ProgressLogger {
|
|||
}
|
||||
|
||||
/**
|
||||
* <p>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);
|
||||
|
|
Loading…
Reference in a new issue