diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 667288ad6..f6b961fd5 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3499e0b85..115e6ac0a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Tue Oct 29 18:00:54 CDT 2013 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https://github.com/gradle/gradle-distributions/releases/download/v1.8.0/gradle-1.8-bin.zip diff --git a/gradlew b/gradlew index 91a7e269e..cccdd3d51 100755 --- a/gradlew +++ b/gradlew @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh ############################################################################## ## @@ -6,20 +6,38 @@ ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" -warn ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -30,6 +48,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,31 +59,11 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -90,7 +89,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -114,6 +113,7 @@ fi if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` @@ -154,11 +154,19 @@ if $cygwin ; then esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 8a0b282aa..f9553162f 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -8,14 +8,14 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome @@ -46,10 +46,9 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. @@ -60,11 +59,6 @@ set _SKIP=2 if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ :execute @rem Setup the command line diff --git a/src/main/java/net/minecraftforge/gradle/FileUtils.java b/src/main/java/net/minecraftforge/gradle/FileUtils.java new file mode 100644 index 000000000..cbae3c53b --- /dev/null +++ b/src/main/java/net/minecraftforge/gradle/FileUtils.java @@ -0,0 +1,31 @@ +package net.minecraftforge.gradle; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.Objects; + +public class FileUtils { + public static String readString(File file) throws IOException { + return readString(file, StandardCharsets.UTF_8); + } + + public static String readString(File file, Charset charset) throws IOException { + return new String(Files.readAllBytes(file.toPath()), charset); + } + + public static void updateDate(File file) throws IOException { + if (!file.createNewFile() && !file.setLastModified(System.currentTimeMillis())) { + throw new IOException("Unable to update modification time of " + file); + } + } + + public static String getFileExtension(String fullName) { + Objects.requireNonNull(fullName); + String fileName = new File(fullName).getName(); + int dotIndex = fileName.lastIndexOf('.'); + return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1); + } +} diff --git a/src/main/java/net/minecraftforge/gradle/ZipFileTree.java b/src/main/java/net/minecraftforge/gradle/ZipFileTree.java index c3ab7e3be..19f0ff5e5 100644 --- a/src/main/java/net/minecraftforge/gradle/ZipFileTree.java +++ b/src/main/java/net/minecraftforge/gradle/ZipFileTree.java @@ -36,6 +36,7 @@ import org.gradle.api.file.FileVisitDetails; import org.gradle.api.file.FileVisitor; import org.gradle.api.file.RelativePath; +import org.gradle.api.internal.file.FileSystemSubset; import org.gradle.api.internal.file.collections.MinimalFileTree; import org.gradle.util.DeprecationLogger; import org.gradle.util.GFileUtils; @@ -109,6 +110,16 @@ public void visit(FileVisitor visitor) } } + @Override + public void registerWatchPoints(FileSystemSubset.Builder builder) { + + } + + @Override + public void visitTreeOrBackingFile(FileVisitor fileVisitor) { + + } + private class DetailsImpl implements FileVisitDetails { private final ZipEntry entry; diff --git a/src/main/java/net/minecraftforge/gradle/common/BasePlugin.java b/src/main/java/net/minecraftforge/gradle/common/BasePlugin.java index e68879d17..c7879d295 100644 --- a/src/main/java/net/minecraftforge/gradle/common/BasePlugin.java +++ b/src/main/java/net/minecraftforge/gradle/common/BasePlugin.java @@ -4,7 +4,11 @@ import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.HashMap; +import java.util.List; +import java.util.function.Function; import net.minecraftforge.gradle.FileLogListenner; import net.minecraftforge.gradle.common.version.AssetIndex; @@ -14,10 +18,13 @@ import net.minecraftforge.gradle.delayed.DelayedFile; import net.minecraftforge.gradle.delayed.DelayedFileTree; import net.minecraftforge.gradle.delayed.DelayedString; +import net.minecraftforge.gradle.json.MCVersionManifest; +import net.minecraftforge.gradle.json.version.VersionToString; import net.minecraftforge.gradle.tasks.DownloadAssetsTask; import net.minecraftforge.gradle.tasks.ObtainFernFlowerTask; import net.minecraftforge.gradle.tasks.abstractutil.DownloadTask; +import net.minecraftforge.gradle.tasks.abstractutil.EtagDownloadTask; import org.gradle.api.Action; import org.gradle.api.DefaultTask; import org.gradle.api.Plugin; @@ -63,7 +70,7 @@ public final void apply(Project arg) @Override public void execute(Project proj) { - addMavenRepo(proj, "forge", "http://files.minecraftforge.net/maven"); + addMavenRepo(proj, "forge", "https://files.minecraftforge.net/maven"); proj.getRepositories().mavenCentral(); addMavenRepo(proj, "minecraft", Constants.LIBRARY_URL); } @@ -129,16 +136,108 @@ private void makeObtainTasks() // download tasks DownloadTask task; + EtagDownloadTask etagDlTask; + etagDlTask = makeTask("getVersionJsonIndex", EtagDownloadTask.class); + { + etagDlTask.setUri(delayedString(Constants.MC_JSON_INDEX_URL)); + etagDlTask.setFile(delayedFile(Constants.VERSION_JSON_INDEX)); + etagDlTask.setDieWithError(false); + } + + etagDlTask = makeTask("getVersionJson", EtagDownloadTask.class); + { + class GetVersionJsonUrl extends DelayedString { + public GetVersionJsonUrl() { + super(BasePlugin.this.project, ""); + } + + @Override + public String call() { + try { + MCVersionManifest manifest = JsonFactory.loadMCVersionManifest(delayedFile(Constants.VERSION_JSON_INDEX).call()); + MCVersionManifest.Version version = manifest.findVersion(delayedString("{MC_VERSION}").call()); + return version.url; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + etagDlTask.dependsOn("getVersionJsonIndex"); + etagDlTask.getInputs().file(delayedFile(Constants.VERSION_JSON_INDEX)); + etagDlTask.setUri(new GetVersionJsonUrl()); + etagDlTask.setFile(delayedFile(Constants.VERSION_JSON_INDEX)); + etagDlTask.setDieWithError(false); + //TODO: this is not necessary? + etagDlTask.doLast(new Action() { // normalizes to linux endings + @Override + public void execute(Task task) { + try { + File json = delayedFile(Constants.VERSION_JSON_INDEX).call(); + if (!json.exists()) + return; + + List lines = Files.readAllLines(json.toPath()); + StringBuilder buf = new StringBuilder(); + for (String line : lines) { + buf.append(line).append('\n'); + } + Files.write(json.toPath(), buf.toString().getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + }); + } + + class GetDataFromJson extends DelayedString { + private final VersionToString function; + + public GetDataFromJson(VersionToString function) { + super(BasePlugin.this.project, ""); + this.function = function; + } + + @Override + public String call() { + try { + Version manifest = JsonFactory.loadVersion(delayedFile(Constants.VERSION_JSON_INDEX).call()); + return function.apply(manifest); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + task = makeTask("downloadClient", DownloadTask.class); { + task.getInputs().file(delayedFile(Constants.VERSION_JSON_INDEX)); + task.dependsOn("getVersionJson"); + task.setOutput(delayedFile(Constants.JAR_CLIENT_FRESH)); - task.setUrl(delayedString(Constants.MC_JAR_URL)); + task.setUrl(new GetDataFromJson(new VersionToString() { + @Override + public String apply(Version json) { + return json.downloads.client.url; + } + })); + + } task = makeTask("downloadServer", DownloadTask.class); { + task.getInputs().file(delayedFile(Constants.VERSION_JSON_INDEX)); + task.dependsOn("getVersionJson"); + task.setOutput(delayedFile(Constants.JAR_SERVER_FRESH)); - task.setUrl(delayedString(Constants.MC_SERVER_URL)); + task.setUrl(new GetDataFromJson(new VersionToString() { + @Override + public String apply(Version json) { + return json.downloads.server.url; + } + })); + + } ObtainFernFlowerTask mcpTask = makeTask("downloadMcpTools", ObtainFernFlowerTask.class); @@ -146,31 +245,35 @@ private void makeObtainTasks() mcpTask.setMcpUrl(delayedString(Constants.MCP_URL)); mcpTask.setFfJar(delayedFile(Constants.FERNFLOWER)); } - - DownloadTask getAssetsIndex = makeTask("getAssetsIndex", DownloadTask.class); + + etagDlTask = makeTask("getAssetsIndex", EtagDownloadTask.class); { - getAssetsIndex.setUrl(delayedString(Constants.ASSETS_INDEX_URL)); - getAssetsIndex.setOutput(delayedFile(Constants.ASSETS + "/indexes/{ASSET_INDEX}.json")); - getAssetsIndex.setDoesCache(false); + task.getInputs().file(delayedFile(Constants.VERSION_JSON_INDEX)); + task.dependsOn("getVersionJson"); - getAssetsIndex.doLast(new Action() { - public void execute(Task task) - { - try - { + etagDlTask.setUrl(new GetDataFromJson(new VersionToString() { + @Override + public String apply(Version json) { + return json.assetIndex.url; + } + })); + + + etagDlTask.setFile(delayedFile(Constants.ASSETS + "/indexes/{ASSET_INDEX}.json")); + etagDlTask.setDieWithError(false); + + etagDlTask.doLast(new Action() { + @Override + public void execute(Task task1) { + try { parseAssetIndex(); + } catch (JsonSyntaxException e) { + throw new RuntimeException(e); + } catch (JsonIOException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); } - catch (Exception e) - { - Throwables.propagate(e); - } - } - }); - - getAssetsIndex.getOutputs().upToDateWhen(new Closure(this, null) { - public Boolean call(Object... obj) - { - return false; } }); } diff --git a/src/main/java/net/minecraftforge/gradle/common/Constants.java b/src/main/java/net/minecraftforge/gradle/common/Constants.java index 552a77611..444dd50a3 100644 --- a/src/main/java/net/minecraftforge/gradle/common/Constants.java +++ b/src/main/java/net/minecraftforge/gradle/common/Constants.java @@ -22,137 +22,126 @@ import com.google.common.base.Joiner; -public class Constants -{ +public class Constants { // OS - public static enum OperatingSystem - { + public static enum OperatingSystem { WINDOWS, OSX, LINUX; - public String toString() - { + public String toString() { return StringUtils.lower(name()); } } // OS - public static enum SystemArch - { + public static enum SystemArch { BIT_32, BIT_64; - public String toString() - { + public String toString() { return StringUtils.lower(name()).replace("bit_", ""); } } - public static final OperatingSystem OPERATING_SYSTEM = getOs(); - public static final SystemArch SYSTEM_ARCH = getArch(); + public static final OperatingSystem OPERATING_SYSTEM = getOs(); + public static final SystemArch SYSTEM_ARCH = getArch(); + public static final String HASH_FUNC = "MD5"; + public static final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11"; // extension nam - public static final String EXT_NAME_MC = "minecraft"; + public static final String EXT_NAME_MC = "minecraft"; public static final String EXT_NAME_JENKINS = "jenkins"; // json parser public static final JdomParser PARSER = new JdomParser(); @SuppressWarnings("serial") - public static final Closure CALL_FALSE = new Closure(null){ public Boolean call(Object o){ return false; }}; + public static final Closure CALL_FALSE = new Closure(null) { + public Boolean call(Object o) { + return false; + } + }; // urls - public static final String MC_JAR_URL = "http://s3.amazonaws.com/Minecraft.Download/versions/{MC_VERSION}/{MC_VERSION}.jar"; - public static final String MC_SERVER_URL = "http://s3.amazonaws.com/Minecraft.Download/versions/{MC_VERSION}/minecraft_server.{MC_VERSION}.jar"; - public static final String MCP_URL = "http://files.minecraftforge.net/fernflower_temporary.zip"; - public static final String ASSETS_URL = "http://resources.download.minecraft.net"; - public static final String LIBRARY_URL = "https://libraries.minecraft.net/"; + public static final String MC_JAR_URL = "https://s3.amazonaws.com/Minecraft.Download/versions/{MC_VERSION}/{MC_VERSION}.jar"; + public static final String MC_SERVER_URL = "https://s3.amazonaws.com/Minecraft.Download/versions/{MC_VERSION}/minecraft_server.{MC_VERSION}.jar"; + public static final String MC_JSON_INDEX_URL = "https://piston-meta.mojang.com/mc/game/version_manifest.json"; + public static final String MCP_URL = "https://files.minecraftforge.net/fernflower_temporary.zip"; + public static final String ASSETS_URL = "https://resources.download.minecraft.net"; + public static final String LIBRARY_URL = "https://libraries.minecraft.net/"; public static final String ASSETS_INDEX_URL = "https://s3.amazonaws.com/Minecraft.Download/indexes/{ASSET_INDEX}.json"; - public static final String LOG = ".gradle/gradle.log"; - public static final String ASSETS_INDEX = "legacy"; + public static final String LOG = ".gradle/gradle.log"; + public static final String ASSETS_INDEX = "legacy"; // things in the cache dir. public static final String JAR_CLIENT_FRESH = "{CACHE_DIR}/minecraft/net/minecraft/minecraft/{MC_VERSION}/minecraft-{MC_VERSION}.jar"; public static final String JAR_SERVER_FRESH = "{CACHE_DIR}/minecraft/net/minecraft/minecraft_server/{MC_VERSION}/minecraft_server-{MC_VERSION}.jar"; - public static final String JAR_MERGED = "{CACHE_DIR}/minecraft/net/minecraft/minecraft_merged/{MC_VERSION}/minecraft_merged-{MC_VERSION}.jar"; - public static final String FERNFLOWER = "{CACHE_DIR}/minecraft/fernflower.jar"; - public static final String EXCEPTOR = "{CACHE_DIR}/minecraft/exceptor.jar"; - public static final String ASSETS = "{CACHE_DIR}/minecraft/assets"; - - public static final String DEOBF_JAR = "{BUILD_DIR}/deobfuscated.jar"; - public static final String DEOBF_BIN_JAR = "{BUILD_DIR}/deobfuscated-bin.jar"; - public static final String DECOMP_JAR = "{BUILD_DIR}/decompiled.jar"; - public static final String DECOMP_FMLED = "{BUILD_DIR}/decompiled-fmled.jar"; - public static final String DECOMP_FMLINJECTED = "{BUILD_DIR}/decompiled-fmlinjected.jar"; + public static final String JAR_MERGED = "{CACHE_DIR}/minecraft/net/minecraft/minecraft_merged/{MC_VERSION}/minecraft_merged-{MC_VERSION}.jar"; + public static final String FERNFLOWER = "{CACHE_DIR}/minecraft/fernflower.jar"; + public static final String EXCEPTOR = "{CACHE_DIR}/minecraft/exceptor.jar"; + public static final String ASSETS = "{CACHE_DIR}/minecraft/assets"; + public static final String JSONS_DIR = ASSETS + "/indexes"; + public static final String VERSION_JSON_INDEX = JSONS_DIR + "/{ASSET_INDEX}.json"; + + public static final String DEOBF_JAR = "{BUILD_DIR}/deobfuscated.jar"; + public static final String DEOBF_BIN_JAR = "{BUILD_DIR}/deobfuscated-bin.jar"; + public static final String DECOMP_JAR = "{BUILD_DIR}/decompiled.jar"; + public static final String DECOMP_FMLED = "{BUILD_DIR}/decompiled-fmled.jar"; + public static final String DECOMP_FMLINJECTED = "{BUILD_DIR}/decompiled-fmlinjected.jar"; public static final String DECOMP_FORGEJAVADOCCED = "{BUILD_DIR}/decompiled-forged.jar"; - public static final String DECOMP_FORGED = "{BUILD_DIR}/decompiled-forged-nojd.jar"; - public static final String DECOMP_FORGEINJECTED = "{BUILD_DIR}/decompiled-forgeinjected.jar"; - public static final String DECOMP_REMAPPED = "{BUILD_DIR}/decompiled-remapped.jar"; + public static final String DECOMP_FORGED = "{BUILD_DIR}/decompiled-forged-nojd.jar"; + public static final String DECOMP_FORGEINJECTED = "{BUILD_DIR}/decompiled-forgeinjected.jar"; + public static final String DECOMP_REMAPPED = "{BUILD_DIR}/decompiled-remapped.jar"; // util public static final String NEWLINE = System.getProperty("line.separator"); - private static final OutputStream NULL_OUT = new OutputStream() - { - public void write(int b) throws IOException{} + private static final OutputStream NULL_OUT = new OutputStream() { + public void write(int b) throws IOException { + } }; // helper methods - public static File cacheFile(Project project, String... otherFiles) - { + public static File cacheFile(Project project, String... otherFiles) { return Constants.file(project.getGradle().getGradleUserHomeDir(), otherFiles); } - public static File file(File file, String... otherFiles) - { + public static File file(File file, String... otherFiles) { String othersJoined = Joiner.on('/').join(otherFiles); return new File(file, othersJoined); } - public static File file(String... otherFiles) - { + public static File file(String... otherFiles) { String othersJoined = Joiner.on('/').join(otherFiles); return new File(othersJoined); } - public static List getClassPath() - { + public static List getClassPath() { URL[] urls = ((URLClassLoader) DevExtension.class.getClassLoader()).getURLs(); ArrayList list = new ArrayList(); - for (URL url : urls) - { + for (URL url : urls) { list.add(url.getPath()); } return list; } - private static OperatingSystem getOs() - { + private static OperatingSystem getOs() { String name = StringUtils.lower(System.getProperty("os.name")); - if (name.contains("windows")) - { + if (name.contains("windows")) { return OperatingSystem.WINDOWS; - } - else if (name.contains("mac") || name.contains("osx")) - { + } else if (name.contains("mac") || name.contains("osx")) { return OperatingSystem.OSX; - } - else if (name.contains("linux") || name.contains("unix")) - { + } else if (name.contains("linux") || name.contains("unix")) { return OperatingSystem.LINUX; - } - else - { + } else { return null; } } - public static File getMinecraftDirectory() - { + public static File getMinecraftDirectory() { String userDir = System.getProperty("user.home"); - switch (OPERATING_SYSTEM) - { + switch (OPERATING_SYSTEM) { case LINUX: return new File(userDir, ".minecraft/"); case WINDOWS: @@ -164,30 +153,23 @@ public static File getMinecraftDirectory() default: return new File(userDir, "minecraft/"); } - } + } - private static SystemArch getArch() - { + private static SystemArch getArch() { String name = StringUtils.lower(System.getProperty("os.arch")); - if (name.contains("64")) - { + if (name.contains("64")) { return SystemArch.BIT_64; - } - else - { + } else { return SystemArch.BIT_32; } } - public static String hash(File file) - { + public static String hash(File file) { return hash(file, "MD5"); } - public static String hash(File file, String function) - { - try - { + public static String hash(File file, String function) { + try { InputStream fis = new FileInputStream(file); @@ -195,11 +177,9 @@ public static String hash(File file, String function) MessageDigest complete = MessageDigest.getInstance(function); int numRead; - do - { + do { numRead = fis.read(buffer); - if (numRead > 0) - { + if (numRead > 0) { complete.update(buffer, 0, numRead); } } while (numRead != -1); @@ -209,37 +189,29 @@ public static String hash(File file, String function) String result = ""; - for (int i = 0; i < hash.length; i++) - { + for (int i = 0; i < hash.length; i++) { result += Integer.toString((hash[i] & 0xff) + 0x100, 16).substring(1); } return result; - } - catch (Exception e) - { + } catch (Exception e) { e.printStackTrace(); } return null; } - public static String hash(String str) - { - try - { + public static String hash(String str) { + try { MessageDigest complete = MessageDigest.getInstance("MD5"); byte[] hash = complete.digest(str.getBytes()); String result = ""; - for (int i = 0; i < hash.length; i++) - { + for (int i = 0; i < hash.length; i++) { result += Integer.toString((hash[i] & 0xff) + 0x100, 16).substring(1); } return result; - } - catch (Exception e) - { + } catch (Exception e) { e.printStackTrace(); } @@ -249,8 +221,7 @@ public static String hash(String str) /** * DON'T FORGET TO CLOSE */ - public static OutputStream getNullStream() - { + public static OutputStream getNullStream() { return NULL_OUT; } } diff --git a/src/main/java/net/minecraftforge/gradle/common/version/Version.java b/src/main/java/net/minecraftforge/gradle/common/version/Version.java index 41121bff7..1bb06f141 100644 --- a/src/main/java/net/minecraftforge/gradle/common/version/Version.java +++ b/src/main/java/net/minecraftforge/gradle/common/version/Version.java @@ -5,6 +5,7 @@ import java.util.List; import net.minecraftforge.gradle.common.Constants; +import net.minecraftforge.gradle.json.version.Downloads; public class Version { @@ -19,6 +20,8 @@ public class Version public String incompatibilityReason; private String assets; public List rules; + public Downloads downloads; + public Downloads.DownloadFileInfo assetIndex; private List _libraries; diff --git a/src/main/java/net/minecraftforge/gradle/common/version/json/JsonFactory.java b/src/main/java/net/minecraftforge/gradle/common/version/json/JsonFactory.java index a0dcff630..b9485a77c 100644 --- a/src/main/java/net/minecraftforge/gradle/common/version/json/JsonFactory.java +++ b/src/main/java/net/minecraftforge/gradle/common/version/json/JsonFactory.java @@ -13,6 +13,7 @@ import com.google.gson.GsonBuilder; import com.google.gson.JsonIOException; import com.google.gson.JsonSyntaxException; +import net.minecraftforge.gradle.json.MCVersionManifest; public class JsonFactory { @@ -43,4 +44,11 @@ public static AssetIndex loadAssetsIndex(File json) throws JsonSyntaxException, reader.close(); return a; } + + public static MCVersionManifest loadMCVersionManifest(File json) throws JsonSyntaxException, JsonIOException, IOException { + FileReader reader = new FileReader(json); + MCVersionManifest a = GSON.fromJson(reader, MCVersionManifest.class); + reader.close(); + return a; + } } diff --git a/src/main/java/net/minecraftforge/gradle/json/MCVersionManifest.java b/src/main/java/net/minecraftforge/gradle/json/MCVersionManifest.java new file mode 100644 index 000000000..7abde652a --- /dev/null +++ b/src/main/java/net/minecraftforge/gradle/json/MCVersionManifest.java @@ -0,0 +1,32 @@ +package net.minecraftforge.gradle.json; + +import java.util.Date; +import java.util.List; + +// format of https://piston-meta.mojang.com/mc/game/version_manifest.json +public class MCVersionManifest { + public LatestInfo latest; + public List versions; + + public Version findVersion(String versionId) { + for (Version v : versions) { + if (versionId.equals(v.id)) { + return v; + } + } + throw new IllegalArgumentException(versionId + " not found"); + } + + public static class LatestInfo { + public String release; + public String snapshot; + } + + public static class Version { + public String id; + public String type; + public String url; + public Date time; + public Date releaseTime; + } +} diff --git a/src/main/java/net/minecraftforge/gradle/json/version/Downloads.java b/src/main/java/net/minecraftforge/gradle/json/version/Downloads.java new file mode 100644 index 000000000..691d2155d --- /dev/null +++ b/src/main/java/net/minecraftforge/gradle/json/version/Downloads.java @@ -0,0 +1,14 @@ +package net.minecraftforge.gradle.json.version; + + +public class Downloads { + public DownloadFileInfo client; + public DownloadFileInfo server; + public DownloadFileInfo windows_server; + + public static class DownloadFileInfo { + public String sha1; + public long size; + public String url; + } +} diff --git a/src/main/java/net/minecraftforge/gradle/json/version/VersionToString.java b/src/main/java/net/minecraftforge/gradle/json/version/VersionToString.java new file mode 100644 index 000000000..afe55b40a --- /dev/null +++ b/src/main/java/net/minecraftforge/gradle/json/version/VersionToString.java @@ -0,0 +1,7 @@ +package net.minecraftforge.gradle.json.version; + +import net.minecraftforge.gradle.common.version.Version; + +public interface VersionToString { + String apply(Version version); +} diff --git a/src/main/java/net/minecraftforge/gradle/tasks/GenSrgTask.java b/src/main/java/net/minecraftforge/gradle/tasks/GenSrgTask.java index 4ae0c39c4..e67ce818e 100644 --- a/src/main/java/net/minecraftforge/gradle/tasks/GenSrgTask.java +++ b/src/main/java/net/minecraftforge/gradle/tasks/GenSrgTask.java @@ -62,6 +62,7 @@ public void doTask() throws IOException File deobfFile = getNotchToMcpSrg(); File reobfFile = getMcpToSrgSrg(); + File notchFile = getMcpToNotchSrg(); // verify files... if (!deobfFile.exists()) @@ -74,6 +75,11 @@ public void doTask() throws IOException reobfFile.getParentFile().mkdirs(); reobfFile.createNewFile(); } + if (!notchFile.exists()) + { + notchFile.getParentFile().mkdirs(); + notchFile.createNewFile(); + } // create streams BufferedReader srgIn = Files.newReader(getInSrg(), Charset.defaultCharset()); diff --git a/src/main/java/net/minecraftforge/gradle/tasks/abstractutil/EtagDownloadTask.java b/src/main/java/net/minecraftforge/gradle/tasks/abstractutil/EtagDownloadTask.java new file mode 100644 index 000000000..61ed8e8ed --- /dev/null +++ b/src/main/java/net/minecraftforge/gradle/tasks/abstractutil/EtagDownloadTask.java @@ -0,0 +1,137 @@ +package net.minecraftforge.gradle.tasks.abstractutil; + +import com.google.common.base.Strings; +import com.google.common.io.ByteStreams; +import groovy.lang.Closure; +import net.minecraftforge.gradle.FileUtils; +import net.minecraftforge.gradle.common.Constants; +import org.gradle.api.DefaultTask; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.Internal; +import org.gradle.api.tasks.OutputFile; +import org.gradle.api.tasks.TaskAction; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; + +public class EtagDownloadTask extends DefaultTask { + Object uri; + Object file; + boolean dieWithError; + + @TaskAction + public void doTask() throws IOException, URISyntaxException { + URI uri = getUri(); + File outFile = getFile(); + File etagFile = getProject().file(getFile().getPath() + ".etag"); + + // ensure folder exists + outFile.getParentFile().mkdirs(); + + String etag; + if (etagFile.exists()) { + etag = FileUtils.readString(etagFile); + } else { + etag = ""; + } + + try { + HttpURLConnection con = (HttpURLConnection) uri.toURL().openConnection(); + con.setInstanceFollowRedirects(true); + con.setRequestProperty("User-Agent", Constants.USER_AGENT); + con.setRequestProperty("If-None-Match", etag); + + con.connect(); + + switch (con.getResponseCode()) { + case 404: // file not found.... duh... + error(uri + " 404'ed!"); + break; + case 304: // content is the same. + this.setDidWork(false); + break; + case 200: // worked + + // write file + InputStream stream = con.getInputStream(); + Files.write(outFile.toPath(), ByteStreams.toByteArray(stream)); + stream.close(); + + // write etag + etag = con.getHeaderField("ETag"); + if (!Strings.isNullOrEmpty(etag)) { + Files.write(etagFile.toPath(), etag.getBytes(StandardCharsets.UTF_8)); + } + + break; + default: // another code?? uh.. + error("Unexpected reponse " + con.getResponseCode() + " from " + uri); + break; + } + + con.disconnect(); + } catch (Throwable e) { + // just in case people dont have internet at the moment. + error(e.getLocalizedMessage()); + } + } + + private void error(String error) { + if (dieWithError) { + throw new RuntimeException(error); + } else { + getLogger().error(error); + } + } + + @Deprecated + @Internal + public URL getUrl() throws MalformedURLException { + try { + return getUri().toURL(); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + + @Deprecated + public void setUrl(Object url) { + this.setUri(url); + } + + @Input + public URI getUri() throws URISyntaxException { + while (uri instanceof Closure) { + uri = ((Closure) uri).call(); + } + + return new URI(uri.toString()); + } + + public void setUri(Object url) { + this.uri = url; + } + + @OutputFile + public File getFile() { + return getProject().file(file); + } + + public void setFile(Object file) { + this.file = file; + } + + @Input + public boolean isDieWithError() { + return dieWithError; + } + + public void setDieWithError(boolean dieWithError) { + this.dieWithError = dieWithError; + } +} + diff --git a/src/main/java/net/minecraftforge/gradle/tasks/dev/ObfuscateTask.java b/src/main/java/net/minecraftforge/gradle/tasks/dev/ObfuscateTask.java index a2397938f..bf80444f2 100644 --- a/src/main/java/net/minecraftforge/gradle/tasks/dev/ObfuscateTask.java +++ b/src/main/java/net/minecraftforge/gradle/tasks/dev/ObfuscateTask.java @@ -89,7 +89,8 @@ private void executeTask(AbstractTask task) { for (Object dep : task.getTaskDependencies().getDependencies(task)) { - executeTask((AbstractTask) dep); + if (dep instanceof AbstractTask) + executeTask((AbstractTask) dep); } if (!task.getState().getExecuted()) diff --git a/src/main/java/net/minecraftforge/gradle/user/UserBasePlugin.java b/src/main/java/net/minecraftforge/gradle/user/UserBasePlugin.java index 29c118af6..f36c20442 100644 --- a/src/main/java/net/minecraftforge/gradle/user/UserBasePlugin.java +++ b/src/main/java/net/minecraftforge/gradle/user/UserBasePlugin.java @@ -58,14 +58,9 @@ import net.minecraftforge.gradle.tasks.user.SourceCopyTask; import net.minecraftforge.gradle.tasks.user.reobf.ArtifactSpec; import net.minecraftforge.gradle.tasks.user.reobf.ReobfTask; +import org.gradle.api.*; -import org.gradle.api.Action; -import org.gradle.api.DefaultTask; -import org.gradle.api.Project; -import org.gradle.api.Task; -import org.gradle.api.XmlProvider; import org.gradle.api.artifacts.Configuration; -import org.gradle.api.artifacts.Configuration.State; import org.gradle.api.artifacts.dsl.DependencyHandler; import org.gradle.api.execution.TaskExecutionGraph; import org.gradle.api.internal.plugins.DslObject; @@ -78,7 +73,6 @@ import org.gradle.api.tasks.compile.JavaCompile; import org.gradle.api.tasks.javadoc.Javadoc; import org.gradle.api.tasks.scala.ScalaCompile; -import org.gradle.listener.ActionBroadcast; import org.gradle.plugins.ide.eclipse.model.Classpath; import org.gradle.plugins.ide.eclipse.model.ClasspathEntry; import org.gradle.plugins.ide.eclipse.model.EclipseModel; @@ -409,19 +403,14 @@ protected void configureEclipse() eclipseConv.getClasspath().setDownloadJavadoc(true); eclipseConv.getClasspath().setDownloadSources(true); - ((ActionBroadcast) eclipseConv.getClasspath().getFile().getWhenMerged()).add(new Action() - { + eclipseConv.getClasspath().getFile().whenMerged(new Action() { @Override - public void execute(Classpath classpath) - { + public void execute(Classpath classpath) { String natives = delayedString(NATIVES_DIR).call().replace('\\', '/'); - for (ClasspathEntry e : classpath.getEntries()) - { - if (e instanceof Library) - { + for (ClasspathEntry e : classpath.getEntries()) { + if (e instanceof Library) { Library lib = (Library) e; - if (lib.getPath().contains("lwjg") || lib.getPath().contains("jinput")) - { + if (lib.getPath().contains("lwjg") || lib.getPath().contains("jinput")) { lib.setNativeLibraryLocation(natives); } } @@ -829,20 +818,14 @@ public void afterEvaluate() // link sources and javadocs eclipse EclipseModel eclipseConv = (EclipseModel) project.getExtensions().getByName("eclipse"); - ((ActionBroadcast) eclipseConv.getClasspath().getFile().getWhenMerged()).add(new Action() - { - FileReferenceFactory factory = new FileReferenceFactory(); - + eclipseConv.getClasspath().getFile().whenMerged(new Action() { + final FileReferenceFactory factory = new FileReferenceFactory(); @Override - public void execute(Classpath classpath) - { - for (ClasspathEntry e : classpath.getEntries()) - { - if (e instanceof Library) - { + public void execute(Classpath classpath) { + for (ClasspathEntry e : classpath.getEntries()) { + if (e instanceof Library) { Library lib = (Library) e; - if (lib.getLibrary().getFile().equals(deobfOut)) - { + if (lib.getLibrary().getFile().equals(deobfOut)) { lib.setJavadocPath(factory.fromFile(project.getConfigurations().getByName(CONFIG_API_JAVADOCS).getSingleFile())); lib.setSourcePath(factory.fromFile(project.getConfigurations().getByName(CONFIG_API_SRC).getSingleFile())); } @@ -853,20 +836,14 @@ public void execute(Classpath classpath) // link sources and javadocs ntellij idea IdeaModel ideaConv = (IdeaModel) project.getExtensions().getByName("idea"); - ((ActionBroadcast) ideaConv.getModule().getIml().getWhenMerged()).add(new Action() { - + ideaConv.getModule().getIml().whenMerged(new Action() { PathFactory factory = new PathFactory(); - @Override - public void execute(Module module) - { - for (Dependency d : module.getDependencies()) - { - if (d instanceof SingleEntryModuleLibrary) - { + public void execute(Module module) { + for (Dependency d : module.getDependencies()) { + if (d instanceof SingleEntryModuleLibrary) { SingleEntryModuleLibrary lib = (SingleEntryModuleLibrary) d; - if (lib.getLibraryFile().equals(deobfOut)) - { + if (lib.getLibraryFile().equals(deobfOut)) { lib.getJavadoc().add(factory.path("jar://" + project.getConfigurations().getByName(CONFIG_API_JAVADOCS).getSingleFile().getAbsolutePath().replace('\\', '/') + "!/")); lib.getSources().add(factory.path("jar://" + project.getConfigurations().getByName(CONFIG_API_SRC).getSingleFile().getAbsolutePath().replace('\\', '/') + "!/")); } @@ -945,7 +922,7 @@ private void readAndApplyJson(File file, String depConfig, String nativeConfig, DependencyHandler handler = project.getDependencies(); // actual dependencies - if (project.getConfigurations().getByName(depConfig).getState() == State.UNRESOLVED) + if (project.getConfigurations().getByName(depConfig).getState() == Configuration.State.UNRESOLVED) { for (net.minecraftforge.gradle.common.version.Library lib : version.getLibraries()) { @@ -957,7 +934,7 @@ private void readAndApplyJson(File file, String depConfig, String nativeConfig, log.info("RESOLVED: " + depConfig); // the natives - if (project.getConfigurations().getByName(nativeConfig).getState() == State.UNRESOLVED) + if (project.getConfigurations().getByName(nativeConfig).getState() == Configuration.State.UNRESOLVED) { for (net.minecraftforge.gradle.common.version.Library lib : version.getLibraries()) {