diff --git a/build.gradle b/build.gradle index 776c4beaa..2d3137fff 100755 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,3 @@ -import java.util.jar.JarEntry -import java.util.jar.JarFile -import java.util.jar.JarOutputStream - /* * This file is part of Baritone. * @@ -103,33 +99,3 @@ jar { preserveFileTimestamps = false reproducibleFileOrder = true } - -build { - // while "jar" supports preserveFileTimestamps false - // reobfJar doesn't, it just sets all the last modified times to that instant where it runs the reobfuscator - // so we have to set all those last modified times back to zero - doLast { - File jarFile = new File("build/libs/baritone-" + version + ".jar") - JarFile jf = new JarFile(jarFile) - JarOutputStream jos = new JarOutputStream(new FileOutputStream(new File("temp.jar"))) - jf.entries().unique { it.name }.sort { it.name }.each { - if (it.name != "META-INF/fml_cache_annotation.json" && it.name != "META-INF/fml_cache_class_versions.json") { - JarEntry clone = new JarEntry(it) - clone.time = 0 - jos.putNextEntry(clone) - copy(jf.getInputStream(it), jos) - } - } - jos.finish() - jf.close() - file("temp.jar").renameTo(jarFile) - } -} - -void copy(InputStream is, OutputStream os) { - byte[] buffer = new byte[1024] - int len = 0 - while ((len = is.read(buffer)) != -1) { - os.write(buffer, 0, len) - } -} diff --git a/scripts/Determinizer.java b/scripts/Determinizer.java new file mode 100644 index 000000000..e15f0b2c7 --- /dev/null +++ b/scripts/Determinizer.java @@ -0,0 +1,49 @@ +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; +import java.util.stream.Collectors; + +/** + * Make a .jar file deterministic by sorting all entries by name, and setting all the last modified times to 0. + * This makes the build 100% reproducible since the timestamp when you built it no longer affects the final file. + * @author leijurv + */ +public class Determinizer { + + public static void main(String[] args) throws IOException { + System.out.println("Input path: " + args[0] + " Output path: " + args[1]); + JarFile jarFile = new JarFile(new File(args[0])); + JarOutputStream jos = new JarOutputStream(new FileOutputStream(new File(args[1]))); + ArrayList entries = jarFile.stream().collect(Collectors.toCollection(ArrayList::new)); + entries.sort(Comparator.comparing(JarEntry::getName)); + for (JarEntry entry : entries) { + if (entry.getName().equals("META-INF/fml_cache_annotation.json")) { + continue; + } + if (entry.getName().equals("META-INF/fml_cache_class_versions.json")) { + continue; + } + JarEntry clone = new JarEntry(entry.getName()); + clone.setTime(0); + jos.putNextEntry(clone); + copy(jarFile.getInputStream(entry), jos); + } + jos.finish(); + jarFile.close(); + } + + public static void copy(InputStream is, OutputStream os) throws IOException { + byte[] buffer = new byte[1024]; + int len; + while ((len = is.read(buffer)) != -1) { + os.write(buffer, 0, len); + } + } +} diff --git a/scripts/build.sh b/scripts/build.sh index 94b02ebf8..6bdb6e5ed 100644 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -3,9 +3,17 @@ set -e # this makes the whole script fail immediately if any one of these comman ./gradlew build export VERSION=$(cat build.gradle | grep "version '" | cut -d "'" -f 2-2) +cd scripts +javac Determinizer.java +java Determinizer ../build/libs/baritone-$VERSION.jar temp.jar +mv temp.jar ../build/libs/baritone-$VERSION.jar +cd .. + + wget -nv https://downloads.sourceforge.net/project/proguard/proguard/6.0/proguard6.0.3.zip unzip proguard6.0.3.zip 2>&1 > /dev/null cd build/libs +rm -rf api.pro echo "-injars 'baritone-$VERSION.jar'" >> api.pro # insert current version cat ../../scripts/proguard.pro | grep -v "this is the rt jar" | grep -v "\-injars" >> api.pro # remove default rt jar and injar lines echo "-libraryjars '$(java -verbose 2>/dev/null | sed -ne '1 s/\[Opened \(.*\)\]/\1/p')'" >> api.pro # insert correct rt.jar location @@ -16,11 +24,17 @@ cat api.pro | grep -v "this is the keep api" > standalone.pro # standalone doesn mkdir -p tempLibraries cat ../../scripts/proguard.pro | grep tempLibraries | grep .jar | cut -d "/" -f 2- | cut -d "'" -f -1 | xargs -n1 -I{} bash -c "find ~/.gradle -name {}" | tee /dev/stderr | xargs -n1 -I{} cp {} tempLibraries +rm -rf ../../dist mkdir ../../dist java -jar ../../proguard6.0.3/lib/proguard.jar @api.pro -mv Obfuscated/baritone-$VERSION.jar ../../dist/baritone-api-$VERSION.jar +cd ../../scripts +java Determinizer ../build/libs/Obfuscated/baritone-$VERSION.jar ../dist/baritone-api-$VERSION.jar +cd ../build/libs +rm -rf Obfuscated/* java -jar ../../proguard6.0.3/lib/proguard.jar @standalone.pro -mv Obfuscated/baritone-$VERSION.jar ../../dist/baritone-standalone-$VERSION.jar +cd ../../scripts +java Determinizer ../build/libs/Obfuscated/baritone-$VERSION.jar ../dist/baritone-standalone-$VERSION.jar +cd ../build/libs mv baritone-$VERSION.jar ../../dist/baritone-unoptimized-$VERSION.jar cd ../../dist shasum * | tee checksums.txt