2014-11-26 16:56:48 +11:00
package org.spigotmc.builder ;
import com.google.common.base.Charsets ;
2018-08-30 09:55:21 +10:00
import com.google.common.base.Preconditions ;
2014-11-26 16:56:48 +11:00
import com.google.common.base.Predicate ;
import com.google.common.base.Throwables ;
import com.google.common.collect.Iterables ;
2017-11-09 10:46:32 +11:00
import com.google.common.collect.ObjectArrays ;
2019-03-25 21:30:02 +11:00
import com.google.common.hash.HashFunction ;
2014-11-26 16:56:48 +11:00
import com.google.common.hash.Hasher ;
import com.google.common.hash.Hashing ;
import com.google.common.io.ByteStreams ;
2015-01-13 10:11:24 +11:00
import com.google.common.io.CharStreams ;
2014-11-26 16:56:48 +11:00
import com.google.common.io.Files ;
import com.google.common.io.Resources ;
2015-01-13 10:11:24 +11:00
import com.google.gson.Gson ;
2014-11-26 16:56:48 +11:00
import difflib.DiffUtils ;
import difflib.Patch ;
2015-08-31 19:31:00 +03:00
import java.awt.Desktop ;
2014-12-12 11:21:43 +11:00
import java.io.BufferedOutputStream ;
2014-11-26 16:56:48 +11:00
import java.io.BufferedReader ;
import java.io.BufferedWriter ;
import java.io.File ;
2014-12-12 11:21:43 +11:00
import java.io.FileDescriptor ;
import java.io.FileNotFoundException ;
2014-11-26 16:56:48 +11:00
import java.io.FileOutputStream ;
import java.io.FileWriter ;
2014-12-07 00:35:01 -05:00
import java.io.FilenameFilter ;
2014-11-26 16:56:48 +11:00
import java.io.IOException ;
import java.io.InputStream ;
import java.io.InputStreamReader ;
import java.io.OutputStream ;
import java.io.PrintStream ;
2018-12-14 10:32:52 +11:00
import java.lang.management.ManagementFactory ;
2015-08-31 19:31:00 +03:00
import java.net.URI ;
2014-11-26 16:56:48 +11:00
import java.net.URL ;
2015-01-13 10:11:24 +11:00
import java.net.URLConnection ;
2018-12-14 20:17:01 +11:00
import java.nio.file.FileSystemException ;
2014-12-08 01:41:20 +02:00
import java.security.KeyManagementException ;
import java.security.NoSuchAlgorithmException ;
2014-12-12 11:21:43 +11:00
import java.security.SecureRandom ;
2014-12-08 01:41:20 +02:00
import java.security.cert.X509Certificate ;
2016-03-01 08:31:47 +11:00
import java.text.MessageFormat ;
2014-12-06 09:12:53 +11:00
import java.util.Arrays ;
2019-12-21 10:33:33 +11:00
import java.util.Collections ;
2014-11-26 16:56:48 +11:00
import java.util.Date ;
import java.util.Enumeration ;
import java.util.List ;
import java.util.zip.ZipEntry ;
import java.util.zip.ZipFile ;
2014-12-08 01:41:20 +02:00
import javax.net.ssl.HostnameVerifier ;
import javax.net.ssl.HttpsURLConnection ;
import javax.net.ssl.SSLContext ;
import javax.net.ssl.SSLSession ;
import javax.net.ssl.TrustManager ;
import javax.net.ssl.X509TrustManager ;
2015-08-31 19:31:00 +03:00
import javax.swing.JFrame ;
import javax.swing.JLabel ;
2015-02-23 09:32:50 +00:00
import joptsimple.OptionParser ;
import joptsimple.OptionSet ;
import joptsimple.OptionSpec ;
2019-12-21 10:33:33 +11:00
import joptsimple.util.EnumConverter ;
2014-11-26 16:56:48 +11:00
import lombok.RequiredArgsConstructor ;
import org.apache.commons.io.FileUtils ;
2014-12-12 11:21:43 +11:00
import org.apache.commons.io.output.TeeOutputStream ;
2014-11-26 16:56:48 +11:00
import org.eclipse.jgit.api.Git ;
import org.eclipse.jgit.api.ResetCommand ;
import org.eclipse.jgit.api.errors.GitAPIException ;
2018-12-18 17:04:10 +11:00
import org.eclipse.jgit.api.errors.JGitInternalException ;
2015-09-02 07:32:27 +10:00
import org.eclipse.jgit.lib.StoredConfig ;
2014-11-26 16:56:48 +11:00
import org.eclipse.jgit.revwalk.RevCommit ;
public class Builder
{
2014-12-12 11:21:43 +11:00
public static final String LOG_FILE = " BuildTools.log.txt " ;
2014-11-26 16:56:48 +11:00
public static final boolean IS_WINDOWS = System . getProperty ( " os.name " ) . startsWith ( " Windows " ) ;
public static final File CWD = new File ( " . " ) ;
2015-09-02 07:32:27 +10:00
private static final boolean autocrlf = ! " \ n " . equals ( System . getProperty ( " line.separator " ) ) ;
2014-12-12 11:07:46 +11:00
private static boolean dontUpdate ;
2019-12-21 10:33:33 +11:00
private static List < Compile > compile ;
2015-01-12 11:49:04 +11:00
private static boolean generateSource ;
private static boolean generateDocs ;
2015-01-13 10:11:24 +11:00
private static boolean dev ;
2017-02-10 18:35:39 +11:00
private static String applyPatchesShell = " sh " ;
2017-11-09 10:46:32 +11:00
//
private static File msysDir ;
2014-11-26 16:56:48 +11:00
public static void main ( String [ ] args ) throws Exception
{
2019-04-23 16:38:24 +10:00
if ( CWD . getAbsolutePath ( ) . contains ( " ' " ) | | CWD . getAbsolutePath ( ) . contains ( " # " ) | | CWD . getAbsolutePath ( ) . contains ( " ~ " ) | | CWD . getAbsolutePath ( ) . contains ( " ( " ) | | CWD . getAbsolutePath ( ) . contains ( " ) " ) )
2016-03-26 15:58:22 +11:00
{
System . err . println ( " Please do not run in a path with special characters! " ) ;
return ;
}
2020-01-29 12:14:39 +11:00
if ( CWD . getAbsolutePath ( ) . contains ( " Dropbox " ) | | CWD . getAbsolutePath ( ) . contains ( " OneDrive " ) )
{
System . err . println ( " Please do not run BuildTools in a Dropbox, OneDrive, or similar. You can always copy the completed jars there later. " ) ;
return ;
}
2015-09-02 07:33:17 +10:00
if ( false & & System . console ( ) = = null )
2015-08-31 19:31:00 +03:00
{
JFrame jFrame = new JFrame ( ) ;
jFrame . setTitle ( " SpigotMC - BuildTools " ) ;
jFrame . setDefaultCloseOperation ( JFrame . EXIT_ON_CLOSE ) ;
jFrame . getContentPane ( ) . add ( new JLabel ( " You have to run BuildTools through bash (msysgit). Please read our wiki. " ) ) ;
jFrame . pack ( ) ;
jFrame . setVisible ( true ) ;
Desktop . getDesktop ( ) . browse ( new URI ( " https://www.spigotmc.org/wiki/buildtools/ " ) ) ;
return ;
}
2015-02-27 16:22:46 +11:00
// May be null
String buildVersion = Builder . class . getPackage ( ) . getImplementationVersion ( ) ;
int buildNumber = - 1 ;
if ( buildVersion ! = null )
{
String [ ] split = buildVersion . split ( " - " ) ;
if ( split . length = = 4 )
{
try
{
buildNumber = Integer . parseInt ( split [ 3 ] ) ;
} catch ( NumberFormatException ex )
{
}
}
}
System . out . println ( " Loading BuildTools version: " + buildVersion + " (# " + buildNumber + " ) " ) ;
2018-10-20 20:33:03 -07:00
System . out . println ( " Java Version: " + JavaVersion . getCurrentVersion ( ) ) ;
2015-02-27 16:22:46 +11:00
2015-02-23 09:32:50 +00:00
OptionParser parser = new OptionParser ( ) ;
2019-03-17 12:40:22 +11:00
OptionSpec < Void > help = parser . accepts ( " help " , " Show the help " ) ;
OptionSpec < Void > disableCertFlag = parser . accepts ( " disable-certificate-check " , " Disable HTTPS certificate check " ) ;
OptionSpec < Void > disableJavaCheck = parser . accepts ( " disable-java-check " , " Disable Java version check " ) ;
OptionSpec < Void > dontUpdateFlag = parser . accepts ( " dont-update " , " Don't pull updates from Git " ) ;
OptionSpec < Void > skipCompileFlag = parser . accepts ( " skip-compile " , " Skip compilation " ) ;
OptionSpec < Void > generateSourceFlag = parser . accepts ( " generate-source " , " Generate source jar " ) ;
OptionSpec < Void > generateDocsFlag = parser . accepts ( " generate-docs " , " Generate Javadoc jar " ) ;
OptionSpec < Void > devFlag = parser . accepts ( " dev " , " Development mode " ) ;
OptionSpec < File > outputDir = parser . acceptsAll ( Arrays . asList ( " o " , " output-dir " ) , " Final jar output directory " ) . withRequiredArg ( ) . ofType ( File . class ) . defaultsTo ( CWD ) ;
OptionSpec < String > jenkinsVersion = parser . accepts ( " rev " , " Version to build " ) . withRequiredArg ( ) . defaultsTo ( " latest " ) ;
2019-12-21 10:33:33 +11:00
OptionSpec < Compile > toCompile = parser . accepts ( " compile " , " Software to compile " ) . withRequiredArg ( ) . ofType ( Compile . class ) . withValuesConvertedBy ( new EnumConverter < Compile > ( Compile . class )
{
} ) . withValuesSeparatedBy ( ',' ) ;
2015-02-23 09:32:50 +00:00
OptionSet options = parser . parse ( args ) ;
2019-03-17 12:40:22 +11:00
if ( options . has ( help ) )
{
parser . printHelpOn ( System . out ) ;
System . exit ( 0 ) ;
}
2015-02-23 09:32:50 +00:00
if ( options . has ( disableCertFlag ) )
2014-12-12 11:07:46 +11:00
{
2015-02-23 09:32:50 +00:00
disableHttpsCertificateCheck ( ) ;
2014-12-08 01:41:20 +02:00
}
2015-02-23 09:32:50 +00:00
dontUpdate = options . has ( dontUpdateFlag ) ;
generateSource = options . has ( generateSourceFlag ) ;
generateDocs = options . has ( generateDocsFlag ) ;
dev = options . has ( devFlag ) ;
2019-12-21 10:33:33 +11:00
compile = options . valuesOf ( toCompile ) ;
if ( options . has ( skipCompileFlag ) )
{
compile = Collections . singletonList ( Compile . NONE ) ;
System . err . println ( " --skip-compile is deprecated, please use --compile NONE " ) ;
}
2020-01-10 09:19:40 +11:00
if ( ( dev | | dontUpdate ) & & options . has ( jenkinsVersion ) )
{
System . err . println ( " Using --dev or --dont-update with --rev makes no sense, exiting. " ) ;
System . exit ( 1 ) ;
}
2014-12-12 11:21:43 +11:00
logOutput ( ) ;
2017-01-30 08:35:51 +11:00
try
2014-11-26 16:56:48 +11:00
{
2017-01-30 08:35:51 +11:00
runProcess ( CWD , " sh " , " -c " , " exit " ) ;
} catch ( Exception ex )
{
2017-11-09 10:46:32 +11:00
if ( IS_WINDOWS )
{
2019-12-18 13:02:47 +11:00
String gitVersion = " PortableGit-2.24.1.2- " + ( System . getProperty ( " os.arch " ) . endsWith ( " 64 " ) ? " 64 " : " 32 " ) + " -bit " ;
// https://github.com/git-for-windows/git/releases/tag/v2.24.1.windows.2
String gitHash = System . getProperty ( " os.arch " ) . endsWith ( " 64 " ) ? " cb75e4a557e01dd27b5af5eb59dfe28adcbad21638777dd686429dd905d13899 " : " 88f5525999228b0be8bb51788bfaa41b14430904bc65f1d4bbdcf441cac1f7fc " ;
2017-11-09 10:46:32 +11:00
msysDir = new File ( gitVersion , " PortableGit " ) ;
if ( ! msysDir . isDirectory ( ) )
{
System . out . println ( " *** Could not find PortableGit installation, downloading. *** " ) ;
String gitName = gitVersion + " .7z.exe " ;
File gitInstall = new File ( gitVersion , gitName ) ;
2019-03-25 21:30:02 +11:00
gitInstall . deleteOnExit ( ) ;
2017-11-09 10:46:32 +11:00
gitInstall . getParentFile ( ) . mkdirs ( ) ;
if ( ! gitInstall . exists ( ) )
{
2019-03-25 21:30:02 +11:00
download ( " https://static.spigotmc.org/git/ " + gitName , gitInstall , HashFormat . SHA256 , gitHash ) ;
2017-11-09 10:46:32 +11:00
}
System . out . println ( " Extracting downloaded git install " ) ;
// yes to all, silent, don't run. Only -y seems to work
runProcess ( gitInstall . getParentFile ( ) , gitInstall . getAbsolutePath ( ) , " -y " , " -gm2 " , " -nr " ) ;
gitInstall . delete ( ) ;
}
System . out . println ( " *** Using downloaded git " + msysDir + " *** " ) ;
System . out . println ( " *** Please note that this is a beta feature, so if it does not work please also try a manual install of git from https://git-for-windows.github.io/ *** " ) ;
} else
{
System . out . println ( " You must run this jar through bash (msysgit) " ) ;
System . exit ( 1 ) ;
}
2014-11-26 16:56:48 +11:00
}
2019-08-09 20:21:30 +10:00
try
{
runProcess ( CWD , " git " , " --version " ) ;
} catch ( Exception ex )
{
System . out . println ( " Could not successfully run git. Please ensure it is installed and functioning. " + ex . getMessage ( ) ) ;
System . exit ( 1 ) ;
}
2018-01-23 22:41:49 +11:00
2014-11-26 16:56:48 +11:00
try
{
2017-09-22 19:32:13 +10:00
runProcess ( CWD , " git " , " config " , " --global " , " --includes " , " user.name " ) ;
2014-11-26 16:56:48 +11:00
} catch ( Exception ex )
{
System . out . println ( " Git name not set, setting it to default value. " ) ;
2014-12-06 09:12:53 +11:00
runProcess ( CWD , " git " , " config " , " --global " , " user.name " , " BuildTools " ) ;
2014-11-26 16:56:48 +11:00
}
try
{
2017-09-22 19:32:13 +10:00
runProcess ( CWD , " git " , " config " , " --global " , " --includes " , " user.email " ) ;
2014-11-26 16:56:48 +11:00
} catch ( Exception ex )
{
System . out . println ( " Git email not set, setting it to default value. " ) ;
2014-12-06 09:12:53 +11:00
runProcess ( CWD , " git " , " config " , " --global " , " user.email " , " unconfigured@null.spigotmc.org " ) ;
2014-11-26 16:56:48 +11:00
}
File workDir = new File ( " work " ) ;
workDir . mkdir ( ) ;
File bukkit = new File ( " Bukkit " ) ;
if ( ! bukkit . exists ( ) )
{
clone ( " https://hub.spigotmc.org/stash/scm/spigot/bukkit.git " , bukkit ) ;
}
File craftBukkit = new File ( " CraftBukkit " ) ;
if ( ! craftBukkit . exists ( ) )
{
clone ( " https://hub.spigotmc.org/stash/scm/spigot/craftbukkit.git " , craftBukkit ) ;
}
File spigot = new File ( " Spigot " ) ;
if ( ! spigot . exists ( ) )
{
clone ( " https://hub.spigotmc.org/stash/scm/spigot/spigot.git " , spigot ) ;
}
File buildData = new File ( " BuildData " ) ;
if ( ! buildData . exists ( ) )
{
clone ( " https://hub.spigotmc.org/stash/scm/spigot/builddata.git " , buildData ) ;
}
2015-06-10 16:21:17 +01:00
File maven ;
String m2Home = System . getenv ( " M2_HOME " ) ;
2015-07-29 19:54:14 +10:00
if ( m2Home = = null | | ! ( maven = new File ( m2Home ) ) . exists ( ) )
2014-11-26 16:56:48 +11:00
{
2019-03-25 21:30:02 +11:00
String mavenVersion = " apache-maven-3.6.0 " ;
maven = new File ( mavenVersion ) ;
2014-11-26 16:56:48 +11:00
2015-06-10 19:53:41 +10:00
if ( ! maven . exists ( ) )
{
System . out . println ( " Maven does not exist, downloading. Please wait. " ) ;
2019-03-25 21:30:02 +11:00
File mvnTemp = new File ( mavenVersion + " -bin.zip " ) ;
2015-06-10 19:53:41 +10:00
mvnTemp . deleteOnExit ( ) ;
2014-11-26 16:56:48 +11:00
2019-03-25 21:30:02 +11:00
// https://www.apache.org/dist/maven/maven-3/3.6.0/binaries/apache-maven-3.6.0-bin.zip.sha512
download ( " https://static.spigotmc.org/maven/ " + mvnTemp . getName ( ) , mvnTemp , HashFormat . SHA512 , " 7d14ab2b713880538974aa361b987231473fbbed20e83586d542c691ace1139026f232bd46fdcce5e8887f528ab1c3fbfc1b2adec90518b6941235952d3868e9 " ) ;
2015-06-10 19:53:41 +10:00
unzip ( mvnTemp , new File ( " . " ) ) ;
2019-03-25 21:30:02 +11:00
mvnTemp . delete ( ) ;
2015-06-10 19:53:41 +10:00
}
2014-11-26 16:56:48 +11:00
}
2014-12-06 09:21:52 +11:00
String mvn = maven . getAbsolutePath ( ) + " /bin/mvn " ;
2014-11-26 16:56:48 +11:00
Git bukkitGit = Git . open ( bukkit ) ;
Git craftBukkitGit = Git . open ( craftBukkit ) ;
Git spigotGit = Git . open ( spigot ) ;
Git buildGit = Git . open ( buildData ) ;
2018-08-30 09:55:21 +10:00
BuildInfo buildInfo = new BuildInfo ( " Dev Build " , " Development " , 0 , null , new BuildInfo . Refs ( " master " , " master " , " master " , " master " ) ) ;
2015-01-13 10:11:24 +11:00
2014-12-12 11:07:46 +11:00
if ( ! dontUpdate )
{
2015-01-13 10:11:24 +11:00
if ( ! dev )
{
2015-03-01 10:23:32 +11:00
String askedVersion = options . valueOf ( jenkinsVersion ) ;
System . out . println ( " Attempting to build version: ' " + askedVersion + " ' use --rev <version> to override " ) ;
2015-01-13 10:11:24 +11:00
String verInfo ;
try
{
2015-03-01 10:23:32 +11:00
verInfo = get ( " https://hub.spigotmc.org/versions/ " + askedVersion + " .json " ) ;
2015-01-13 10:11:24 +11:00
} catch ( IOException ex )
{
2015-03-01 10:23:32 +11:00
System . err . println ( " Could not get version " + askedVersion + " does it exist? Try another version or use 'latest' " ) ;
2015-01-13 10:11:24 +11:00
ex . printStackTrace ( ) ;
return ;
}
2015-03-01 10:23:32 +11:00
System . out . println ( " Found version " ) ;
2015-01-13 10:11:24 +11:00
System . out . println ( verInfo ) ;
buildInfo = new Gson ( ) . fromJson ( verInfo , BuildInfo . class ) ;
2015-02-27 16:22:46 +11:00
if ( buildNumber ! = - 1 & & buildInfo . getToolsVersion ( ) ! = - 1 & & buildNumber < buildInfo . getToolsVersion ( ) )
{
2016-03-22 14:57:37 +11:00
System . err . println ( " **** Your BuildTools is out of date and will not build the requested version. Please grab a new copy from https://www.spigotmc.org/go/buildtools-dl " ) ;
2015-02-27 16:22:46 +11:00
System . exit ( 1 ) ;
}
2018-08-30 09:55:21 +10:00
if ( ! options . has ( disableJavaCheck ) )
{
if ( buildInfo . getJavaVersions ( ) = = null )
{
buildInfo . setJavaVersions ( new int [ ]
{
JavaVersion . JAVA_7 . getVersion ( ) , JavaVersion . JAVA_8 . getVersion ( )
} ) ;
}
Preconditions . checkArgument ( buildInfo . getJavaVersions ( ) . length = = 2 , " Expected only two Java versions, got %s " , JavaVersion . printVersions ( buildInfo . getJavaVersions ( ) ) ) ;
JavaVersion curVersion = JavaVersion . getCurrentVersion ( ) ;
JavaVersion minVersion = JavaVersion . getByVersion ( buildInfo . getJavaVersions ( ) [ 0 ] ) ;
JavaVersion maxVersion = JavaVersion . getByVersion ( buildInfo . getJavaVersions ( ) [ 1 ] ) ;
if ( curVersion . getVersion ( ) < minVersion . getVersion ( ) | | curVersion . getVersion ( ) > maxVersion . getVersion ( ) )
{
System . err . println ( " *** The version you have requested to build requires Java versions between " + JavaVersion . printVersions ( buildInfo . getJavaVersions ( ) ) + " , but you are using " + curVersion ) ;
System . err . println ( " *** Please rerun BuildTools using an appropriate Java version. For obvious reasons outdated MC versions do not support Java versions that did not exist at their release. " ) ;
System . exit ( 1 ) ;
}
}
2015-01-13 10:11:24 +11:00
}
pull ( buildGit , buildInfo . getRefs ( ) . getBuildData ( ) ) ;
pull ( bukkitGit , buildInfo . getRefs ( ) . getBukkit ( ) ) ;
pull ( craftBukkitGit , buildInfo . getRefs ( ) . getCraftBukkit ( ) ) ;
pull ( spigotGit , buildInfo . getRefs ( ) . getSpigot ( ) ) ;
2014-12-12 11:07:46 +11:00
}
2014-11-26 16:56:48 +11:00
2015-02-27 16:27:23 +11:00
VersionInfo versionInfo = new Gson ( ) . fromJson (
2017-02-10 18:35:39 +11:00
Files . toString ( new File ( " BuildData/info.json " ) , Charsets . UTF_8 ) ,
2015-02-27 16:27:23 +11:00
VersionInfo . class
) ;
// Default to 1.8 builds.
if ( versionInfo = = null )
{
2015-07-29 19:54:14 +10:00
versionInfo = new VersionInfo ( " 1.8 " , " bukkit-1.8.at " , " bukkit-1.8-cl.csrg " , " bukkit-1.8-members.csrg " , " package.srg " , null ) ;
2015-02-27 16:27:23 +11:00
}
System . out . println ( " Attempting to build Minecraft with details: " + versionInfo ) ;
2018-12-13 11:00:00 +11:00
if ( buildNumber ! = - 1 & & versionInfo . getToolsVersion ( ) ! = - 1 & & buildNumber < versionInfo . getToolsVersion ( ) )
{
System . err . println ( " " ) ;
System . err . println ( " **** Your BuildTools is out of date and will not build the requested version. Please grab a new copy from https://www.spigotmc.org/go/buildtools-dl " ) ;
System . exit ( 1 ) ;
}
2015-02-27 16:27:23 +11:00
File vanillaJar = new File ( workDir , " minecraft_server. " + versionInfo . getMinecraftVersion ( ) + " .jar " ) ;
2015-07-29 19:54:14 +10:00
if ( ! vanillaJar . exists ( ) | | ! checkHash ( vanillaJar , versionInfo ) )
2014-11-26 16:56:48 +11:00
{
2017-02-10 18:35:39 +11:00
if ( versionInfo . getServerUrl ( ) ! = null )
{
2019-03-25 21:30:02 +11:00
download ( versionInfo . getServerUrl ( ) , vanillaJar , HashFormat . MD5 , versionInfo . getMinecraftHash ( ) ) ;
2017-02-10 18:35:39 +11:00
} else
{
2019-03-25 21:30:02 +11:00
download ( String . format ( " https://s3.amazonaws.com/Minecraft.Download/versions/%1$s/minecraft_server.%1$s.jar " , versionInfo . getMinecraftVersion ( ) ) , vanillaJar , HashFormat . MD5 , versionInfo . getMinecraftHash ( ) ) ;
2017-02-10 18:35:39 +11:00
// Legacy versions can also specify a specific shell to build with which has to be bash-compatible
applyPatchesShell = System . getenv ( ) . get ( " SHELL " ) ;
if ( applyPatchesShell = = null | | applyPatchesShell . trim ( ) . isEmpty ( ) )
{
applyPatchesShell = " bash " ;
}
}
2014-11-26 16:56:48 +11:00
}
Iterable < RevCommit > mappings = buildGit . log ( )
2019-04-11 09:17:32 +10:00
. addPath ( " mappings/ " )
2014-11-26 16:56:48 +11:00
. setMaxCount ( 1 ) . call ( ) ;
Hasher mappingsHash = Hashing . md5 ( ) . newHasher ( ) ;
for ( RevCommit rev : mappings )
{
mappingsHash . putString ( rev . getName ( ) , Charsets . UTF_8 ) ;
}
String mappingsVersion = mappingsHash . hash ( ) . toString ( ) . substring ( 24 ) ; // Last 8 chars
File finalMappedJar = new File ( workDir , " mapped. " + mappingsVersion + " .jar " ) ;
if ( ! finalMappedJar . exists ( ) )
{
2018-11-24 10:03:35 +11:00
System . out . println ( " Final mapped jar: " + finalMappedJar + " does not exist, creating (please wait)! " ) ;
2014-11-26 16:56:48 +11:00
File clMappedJar = new File ( finalMappedJar + " -cl " ) ;
File mMappedJar = new File ( finalMappedJar + " -m " ) ;
2018-12-13 11:00:00 +11:00
if ( versionInfo . getClassMapCommand ( ) = = null )
{
versionInfo . setClassMapCommand ( " java -jar BuildData/bin/SpecialSource-2.jar map -i {0} -m {1} -o {2} " ) ;
}
runProcess ( CWD , MessageFormat . format ( versionInfo . getClassMapCommand ( ) , vanillaJar . getPath ( ) , " BuildData/mappings/ " + versionInfo . getClassMappings ( ) , clMappedJar . getPath ( ) ) . split ( " " ) ) ;
2014-12-06 09:12:53 +11:00
2018-12-13 11:00:00 +11:00
if ( versionInfo . getMemberMapCommand ( ) = = null )
{
versionInfo . setMemberMapCommand ( " java -jar BuildData/bin/SpecialSource-2.jar map -i {0} -m {1} -o {2} " ) ;
}
runProcess ( CWD , MessageFormat . format ( versionInfo . getMemberMapCommand ( ) , clMappedJar . getPath ( ) ,
" BuildData/mappings/ " + versionInfo . getMemberMappings ( ) , mMappedJar . getPath ( ) ) . split ( " " ) ) ;
2014-12-06 09:12:53 +11:00
2018-12-13 11:00:00 +11:00
if ( versionInfo . getFinalMapCommand ( ) = = null )
{
2018-12-14 19:31:53 +11:00
versionInfo . setFinalMapCommand ( " java -jar BuildData/bin/SpecialSource.jar --kill-lvt -i {0} --access-transformer {1} -m {2} -o {3} " ) ;
2018-12-13 11:00:00 +11:00
}
runProcess ( CWD , MessageFormat . format ( versionInfo . getFinalMapCommand ( ) , mMappedJar . getPath ( ) , " BuildData/mappings/ " + versionInfo . getAccessTransforms ( ) ,
" BuildData/mappings/ " + versionInfo . getPackageMappings ( ) , finalMappedJar . getPath ( ) ) . split ( " " ) ) ;
2014-11-26 16:56:48 +11:00
}
2014-12-06 09:21:52 +11:00
runProcess ( CWD , " sh " , mvn , " install:install-file " , " -Dfile= " + finalMappedJar , " -Dpackaging=jar " , " -DgroupId=org.spigotmc " ,
2015-02-27 16:27:23 +11:00
" -DartifactId=minecraft-server " , " -Dversion= " + versionInfo . getMinecraftVersion ( ) + " -SNAPSHOT " ) ;
2014-11-26 16:56:48 +11:00
File decompileDir = new File ( workDir , " decompile- " + mappingsVersion ) ;
if ( ! decompileDir . exists ( ) )
{
decompileDir . mkdir ( ) ;
File clazzDir = new File ( decompileDir , " classes " ) ;
unzip ( finalMappedJar , clazzDir , new Predicate < String > ( )
{
@Override
public boolean apply ( String input )
{
return input . startsWith ( " net/minecraft/server " ) ;
}
} ) ;
2016-03-01 09:50:21 +11:00
if ( versionInfo . getDecompileCommand ( ) = = null )
{
versionInfo . setDecompileCommand ( " java -jar BuildData/bin/fernflower.jar -dgs=1 -hdc=0 -rbr=0 -asc=1 -udv=0 {0} {1} " ) ;
}
2014-11-26 16:56:48 +11:00
2016-03-01 09:50:21 +11:00
runProcess ( CWD , MessageFormat . format ( versionInfo . getDecompileCommand ( ) , clazzDir . getPath ( ) , decompileDir . getPath ( ) ) . split ( " " ) ) ;
2014-11-26 16:56:48 +11:00
}
2018-12-14 19:57:43 +11:00
try
{
File latestLink = new File ( workDir , " decompile-latest " ) ;
latestLink . delete ( ) ;
java . nio . file . Files . createSymbolicLink ( latestLink . toPath ( ) , decompileDir . getParentFile ( ) . toPath ( ) . relativize ( decompileDir . toPath ( ) ) ) ;
} catch ( UnsupportedOperationException ex )
{
2018-12-14 20:17:01 +11:00
// Ignore if not possible
} catch ( FileSystemException ex )
{
// Not running as admin on Windows
2018-12-14 19:57:43 +11:00
} catch ( IOException ex )
{
2018-12-14 20:17:01 +11:00
System . out . println ( " Did not create decompile-latest link " + ex . getMessage ( ) ) ;
2018-12-14 19:57:43 +11:00
}
2014-11-26 16:56:48 +11:00
System . out . println ( " Applying CraftBukkit Patches " ) ;
File nmsDir = new File ( craftBukkit , " src/main/java/net " ) ;
if ( nmsDir . exists ( ) )
{
System . out . println ( " Backing up NMS dir " ) ;
FileUtils . moveDirectory ( nmsDir , new File ( workDir , " nms.old. " + System . currentTimeMillis ( ) ) ) ;
}
File patchDir = new File ( craftBukkit , " nms-patches " ) ;
for ( File file : patchDir . listFiles ( ) )
{
2017-10-19 21:01:43 +11:00
if ( ! file . getName ( ) . endsWith ( " .patch " ) )
{
continue ;
}
2018-07-14 10:35:43 +10:00
String targetFile = " net/minecraft/server/ " + file . getName ( ) . replace ( " .patch " , " .java " ) ;
2014-11-26 16:56:48 +11:00
File clean = new File ( decompileDir , targetFile ) ;
File t = new File ( nmsDir . getParentFile ( ) , targetFile ) ;
t . getParentFile ( ) . mkdirs ( ) ;
System . out . println ( " Patching with " + file . getName ( ) ) ;
2014-12-24 09:32:10 +11:00
List < String > readFile = Files . readLines ( file , Charsets . UTF_8 ) ;
// Manually append prelude if it is not found in the first few lines.
boolean preludeFound = false ;
for ( int i = 0 ; i < Math . min ( 3 , readFile . size ( ) ) ; i + + )
{
if ( readFile . get ( i ) . startsWith ( " +++ " ) )
{
preludeFound = true ;
break ;
}
}
if ( ! preludeFound )
{
readFile . add ( 0 , " +++ " ) ;
}
Patch parsedPatch = DiffUtils . parseUnifiedDiff ( readFile ) ;
2014-11-26 16:56:48 +11:00
List < ? > modifiedLines = DiffUtils . patch ( Files . readLines ( clean , Charsets . UTF_8 ) , parsedPatch ) ;
BufferedWriter bw = new BufferedWriter ( new FileWriter ( t ) ) ;
for ( String line : ( List < String > ) modifiedLines )
{
bw . write ( line ) ;
bw . newLine ( ) ;
}
bw . close ( ) ;
}
File tmpNms = new File ( craftBukkit , " tmp-nms " ) ;
FileUtils . copyDirectory ( nmsDir , tmpNms ) ;
craftBukkitGit . branchDelete ( ) . setBranchNames ( " patched " ) . setForce ( true ) . call ( ) ;
craftBukkitGit . checkout ( ) . setCreateBranch ( true ) . setForce ( true ) . setName ( " patched " ) . call ( ) ;
craftBukkitGit . add ( ) . addFilepattern ( " src/main/java/net/ " ) . call ( ) ;
craftBukkitGit . commit ( ) . setMessage ( " CraftBukkit $ " + new Date ( ) ) . call ( ) ;
2015-01-13 10:11:24 +11:00
craftBukkitGit . checkout ( ) . setName ( buildInfo . getRefs ( ) . getCraftBukkit ( ) ) . call ( ) ;
2014-11-26 16:56:48 +11:00
FileUtils . moveDirectory ( tmpNms , nmsDir ) ;
2019-04-11 08:59:05 +10:00
if ( versionInfo . getToolsVersion ( ) < 93 )
2014-11-26 16:56:48 +11:00
{
2019-04-11 08:59:05 +10:00
File spigotApi = new File ( spigot , " Bukkit " ) ;
if ( ! spigotApi . exists ( ) )
{
clone ( " file:// " + bukkit . getAbsolutePath ( ) , spigotApi ) ;
}
File spigotServer = new File ( spigot , " CraftBukkit " ) ;
if ( ! spigotServer . exists ( ) )
{
clone ( " file:// " + craftBukkit . getAbsolutePath ( ) , spigotServer ) ;
}
2014-11-26 16:56:48 +11:00
}
// Git spigotApiGit = Git.open( spigotApi );
// Git spigotServerGit = Git.open( spigotServer );
2019-12-21 10:33:33 +11:00
if ( compile = = null | | compile . isEmpty ( ) )
{
if ( versionInfo . getToolsVersion ( ) < = 104 | | dev )
{
compile = Arrays . asList ( Compile . CRAFTBUKKIT , Compile . SPIGOT ) ;
} else
{
compile = Collections . singletonList ( Compile . SPIGOT ) ;
}
}
if ( compile . contains ( Compile . CRAFTBUKKIT ) )
2014-12-12 11:25:00 +11:00
{
System . out . println ( " Compiling Bukkit " ) ;
2019-01-04 20:30:05 +11:00
if ( dev )
{
runProcess ( bukkit , " sh " , mvn , " -P " , " development " , " clean " , " install " ) ;
} else
{
runProcess ( bukkit , " sh " , mvn , " clean " , " install " ) ;
}
2015-01-12 11:49:04 +11:00
if ( generateDocs )
{
runProcess ( bukkit , " sh " , mvn , " javadoc:jar " ) ;
}
if ( generateSource )
{
runProcess ( bukkit , " sh " , mvn , " source:jar " ) ;
}
2014-11-26 16:56:48 +11:00
2014-12-12 11:25:00 +11:00
System . out . println ( " Compiling CraftBukkit " ) ;
2019-01-04 20:30:05 +11:00
if ( dev )
{
runProcess ( craftBukkit , " sh " , mvn , " -P " , " development " , " clean " , " install " ) ;
} else
{
runProcess ( craftBukkit , " sh " , mvn , " clean " , " install " ) ;
}
2014-12-12 11:25:00 +11:00
}
2014-11-26 16:56:48 +11:00
try
{
2017-02-10 18:35:39 +11:00
runProcess ( spigot , applyPatchesShell , " applyPatches.sh " ) ;
2014-11-26 16:56:48 +11:00
System . out . println ( " *** Spigot patches applied! " ) ;
2014-12-12 11:25:00 +11:00
2019-12-21 10:33:33 +11:00
if ( compile . contains ( Compile . SPIGOT ) )
2014-12-12 11:25:00 +11:00
{
2015-05-24 15:56:49 +01:00
System . out . println ( " Compiling Spigot & Spigot-API " ) ;
2019-01-04 20:30:05 +11:00
if ( dev )
{
runProcess ( spigot , " sh " , mvn , " -P " , " development " , " clean " , " install " ) ;
} else
{
runProcess ( spigot , " sh " , mvn , " clean " , " install " ) ;
}
2014-12-12 11:25:00 +11:00
}
2014-11-26 16:56:48 +11:00
} catch ( Exception ex )
{
2016-03-01 19:09:59 +11:00
System . err . println ( " Error compiling Spigot. Please check the wiki for FAQs. " ) ;
System . err . println ( " If this does not resolve your issue then please pastebin the entire BuildTools.log.txt file when seeking support. " ) ;
2014-11-26 16:56:48 +11:00
ex . printStackTrace ( ) ;
2014-11-29 10:49:54 +11:00
System . exit ( 1 ) ;
2014-11-26 16:56:48 +11:00
}
2014-12-07 00:35:01 -05:00
2014-12-12 11:21:43 +11:00
for ( int i = 0 ; i < 35 ; i + + )
{
System . out . println ( " " ) ;
}
2015-04-26 13:10:19 -05:00
2019-12-21 10:33:33 +11:00
System . out . println ( " Success! Everything completed successfully. Copying final .jar files now. " ) ;
2020-01-04 18:45:37 -08:00
if ( ( versionInfo . getToolsVersion ( ) < 101 & & ! compile . contains ( Compile . NONE ) ) | | ( versionInfo . getToolsVersion ( ) > 104 & & compile . contains ( Compile . CRAFTBUKKIT ) ) )
2019-12-21 10:33:33 +11:00
{
copyJar ( " CraftBukkit/target " , " craftbukkit " , new File ( outputDir . value ( options ) , " craftbukkit- " + versionInfo . getMinecraftVersion ( ) + " .jar " ) ) ;
}
if ( compile . contains ( Compile . SPIGOT ) )
2015-04-26 13:10:19 -05:00
{
2017-11-18 09:52:58 +11:00
copyJar ( " Spigot/Spigot-Server/target " , " spigot " , new File ( outputDir . value ( options ) , " spigot- " + versionInfo . getMinecraftVersion ( ) + " .jar " ) ) ;
2015-04-26 13:10:19 -05:00
}
2014-12-07 00:35:01 -05:00
}
2015-07-29 19:54:14 +10:00
private static boolean checkHash ( File vanillaJar , VersionInfo versionInfo ) throws IOException
{
String hash = Files . hash ( vanillaJar , Hashing . md5 ( ) ) . toString ( ) ;
if ( ! dev & & versionInfo . getMinecraftHash ( ) ! = null & & ! hash . equals ( versionInfo . getMinecraftHash ( ) ) )
{
System . err . println ( " **** Warning, Minecraft jar hash of " + hash + " does not match stored hash of " + versionInfo . getMinecraftHash ( ) ) ;
return false ;
} else
{
System . out . println ( " Found good Minecraft hash ( " + hash + " ) " ) ;
return true ;
}
}
2015-01-13 10:11:24 +11:00
public static final String get ( String url ) throws IOException
{
URLConnection con = new URL ( url ) . openConnection ( ) ;
con . setConnectTimeout ( 5000 ) ;
con . setReadTimeout ( 5000 ) ;
InputStreamReader r = null ;
try
{
r = new InputStreamReader ( con . getInputStream ( ) ) ;
return CharStreams . toString ( r ) ;
} finally
{
if ( r ! = null )
{
r . close ( ) ;
}
}
}
2017-11-18 09:52:58 +11:00
public static void copyJar ( String path , final String jarPrefix , File outJar ) throws Exception
2014-12-07 00:35:01 -05:00
{
File [ ] files = new File ( path ) . listFiles ( new FilenameFilter ( )
{
@Override
2014-12-12 11:21:43 +11:00
public boolean accept ( File dir , String name )
2014-12-07 00:35:01 -05:00
{
return name . startsWith ( jarPrefix ) & & name . endsWith ( " .jar " ) ;
}
} ) ;
2017-11-18 09:52:58 +11:00
if ( ! outJar . getParentFile ( ) . isDirectory ( ) )
{
outJar . getParentFile ( ) . mkdirs ( ) ;
}
2014-12-07 00:35:01 -05:00
for ( File file : files )
{
2017-11-18 09:52:58 +11:00
System . out . println ( " Copying " + file . getName ( ) + " to " + outJar . getAbsolutePath ( ) ) ;
Files . copy ( file , outJar ) ;
System . out . println ( " - Saved as " + outJar ) ;
2014-12-07 00:35:01 -05:00
}
2014-11-26 16:56:48 +11:00
}
2015-01-13 10:11:24 +11:00
public static void pull ( Git repo , String ref ) throws Exception
2014-11-26 16:56:48 +11:00
{
System . out . println ( " Pulling updates for " + repo . getRepository ( ) . getDirectory ( ) ) ;
2018-12-18 17:04:10 +11:00
try
{
repo . reset ( ) . setRef ( " origin/master " ) . setMode ( ResetCommand . ResetType . HARD ) . call ( ) ;
} catch ( JGitInternalException ex )
{
System . err . println ( " *** Warning, could not find origin/master ref, but continuing anyway. " ) ;
System . err . println ( " *** If further errors occur please delete " + repo . getRepository ( ) . getDirectory ( ) . getParent ( ) + " and retry. " ) ;
}
2015-01-13 10:11:24 +11:00
repo . fetch ( ) . call ( ) ;
System . out . println ( " Successfully fetched updates! " ) ;
2014-11-26 16:56:48 +11:00
2015-02-27 16:12:05 +11:00
repo . reset ( ) . setRef ( ref ) . setMode ( ResetCommand . ResetType . HARD ) . call ( ) ;
2015-01-13 10:11:24 +11:00
if ( ref . equals ( " master " ) )
2014-11-26 16:56:48 +11:00
{
2015-01-13 10:11:24 +11:00
repo . reset ( ) . setRef ( " origin/master " ) . setMode ( ResetCommand . ResetType . HARD ) . call ( ) ;
2014-11-26 16:56:48 +11:00
}
2015-01-13 10:11:24 +11:00
System . out . println ( " Checked out: " + ref ) ;
2014-11-26 16:56:48 +11:00
}
2014-12-06 09:12:53 +11:00
public static int runProcess ( File workDir , String . . . command ) throws Exception
2017-11-09 10:46:32 +11:00
{
if ( msysDir ! = null )
{
if ( " bash " . equals ( command [ 0 ] ) )
{
command [ 0 ] = " git-bash " ;
}
String [ ] shim = new String [ ]
{
" cmd.exe " , " /C "
} ;
command = ObjectArrays . concat ( shim , command , String . class ) ;
}
return runProcess0 ( workDir , command ) ;
}
private static int runProcess0 ( File workDir , String . . . command ) throws Exception
2014-11-26 16:56:48 +11:00
{
2018-11-24 10:03:35 +11:00
Preconditions . checkArgument ( workDir ! = null , " workDir " ) ;
Preconditions . checkArgument ( command ! = null & & command . length > 0 , " Invalid command " ) ;
if ( command [ 0 ] . equals ( " java " ) )
{
command [ 0 ] = System . getProperty ( " java.home " ) + " /bin/ " + command [ 0 ] ;
}
2015-01-05 14:46:07 +11:00
ProcessBuilder pb = new ProcessBuilder ( command ) ;
pb . directory ( workDir ) ;
pb . environment ( ) . put ( " JAVA_HOME " , System . getProperty ( " java.home " ) ) ;
2018-10-20 15:37:44 +11:00
pb . environment ( ) . remove ( " M2_HOME " ) ; // Just let maven figure this out from where it is invoked
2015-01-05 19:45:18 +11:00
if ( ! pb . environment ( ) . containsKey ( " MAVEN_OPTS " ) )
{
pb . environment ( ) . put ( " MAVEN_OPTS " , " -Xmx1024M " ) ;
}
2018-11-08 20:58:16 +11:00
if ( ! pb . environment ( ) . containsKey ( " _JAVA_OPTIONS " ) )
{
2018-12-14 10:32:52 +11:00
String javaOptions = " -Djdk.net.URLClassPath.disableClassPathURLCheck=true " ;
for ( String arg : ManagementFactory . getRuntimeMXBean ( ) . getInputArguments ( ) )
{
if ( arg . startsWith ( " -Xmx " ) )
{
javaOptions + = " " + arg ;
}
}
pb . environment ( ) . put ( " _JAVA_OPTIONS " , javaOptions ) ;
2018-11-08 20:58:16 +11:00
}
2017-11-09 10:46:32 +11:00
if ( msysDir ! = null )
{
String pathEnv = null ;
for ( String key : pb . environment ( ) . keySet ( ) )
{
if ( key . equalsIgnoreCase ( " path " ) )
{
pathEnv = key ;
}
}
if ( pathEnv = = null )
{
throw new IllegalStateException ( " Could not find path variable! " ) ;
}
2019-12-18 13:02:47 +11:00
String path = msysDir . getAbsolutePath ( ) + " ; " + new File ( msysDir , " bin " ) . getAbsolutePath ( ) + " ; " + pb . environment ( ) . get ( pathEnv ) ;
2017-11-09 10:46:32 +11:00
pb . environment ( ) . put ( pathEnv , path ) ;
}
2015-01-05 14:46:07 +11:00
final Process ps = pb . start ( ) ;
2014-11-26 16:56:48 +11:00
2018-12-01 08:27:24 +11:00
new Thread ( new StreamRedirector ( ps . getInputStream ( ) , System . out ) , " System.out redirector " ) . start ( ) ;
new Thread ( new StreamRedirector ( ps . getErrorStream ( ) , System . err ) , " System.err redirector " ) . start ( ) ;
2014-11-26 16:56:48 +11:00
int status = ps . waitFor ( ) ;
if ( status ! = 0 )
{
2014-12-06 09:12:53 +11:00
throw new RuntimeException ( " Error running command, return status !=0: " + Arrays . toString ( command ) ) ;
2014-11-26 16:56:48 +11:00
}
return status ;
}
@RequiredArgsConstructor
private static class StreamRedirector implements Runnable
{
private final InputStream in ;
private final PrintStream out ;
@Override
public void run ( )
{
BufferedReader br = new BufferedReader ( new InputStreamReader ( in ) ) ;
try
{
String line ;
while ( ( line = br . readLine ( ) ) ! = null )
{
out . println ( line ) ;
}
} catch ( IOException ex )
{
throw Throwables . propagate ( ex ) ;
}
}
}
public static void unzip ( File zipFile , File targetFolder ) throws IOException
{
unzip ( zipFile , targetFolder , null ) ;
}
public static void unzip ( File zipFile , File targetFolder , Predicate < String > filter ) throws IOException
{
targetFolder . mkdir ( ) ;
ZipFile zip = new ZipFile ( zipFile ) ;
2017-11-18 09:45:25 +11:00
try
2014-11-26 16:56:48 +11:00
{
2017-11-18 09:45:25 +11:00
for ( Enumeration < ? extends ZipEntry > entries = zip . entries ( ) ; entries . hasMoreElements ( ) ; )
2014-11-26 16:56:48 +11:00
{
2017-11-18 09:45:25 +11:00
ZipEntry entry = entries . nextElement ( ) ;
if ( filter ! = null )
2014-11-26 16:56:48 +11:00
{
2017-11-18 09:45:25 +11:00
if ( ! filter . apply ( entry . getName ( ) ) )
{
continue ;
}
2014-11-26 16:56:48 +11:00
}
2017-11-18 09:45:25 +11:00
File outFile = new File ( targetFolder , entry . getName ( ) ) ;
2014-11-26 16:56:48 +11:00
2017-11-18 09:45:25 +11:00
if ( entry . isDirectory ( ) )
{
outFile . mkdirs ( ) ;
continue ;
}
if ( outFile . getParentFile ( ) ! = null )
{
outFile . getParentFile ( ) . mkdirs ( ) ;
}
2014-11-26 16:56:48 +11:00
2017-11-18 09:45:25 +11:00
InputStream is = zip . getInputStream ( entry ) ;
OutputStream os = new FileOutputStream ( outFile ) ;
try
{
ByteStreams . copy ( is , os ) ;
} finally
{
is . close ( ) ;
os . close ( ) ;
}
2014-11-26 16:56:48 +11:00
2017-11-18 09:45:25 +11:00
System . out . println ( " Extracted: " + outFile ) ;
}
} finally
{
zip . close ( ) ;
2014-11-26 16:56:48 +11:00
}
}
2015-09-02 07:32:27 +10:00
public static void clone ( String url , File target ) throws GitAPIException , IOException
2014-11-26 16:56:48 +11:00
{
System . out . println ( " Starting clone of " + url + " to " + target ) ;
Git result = Git . cloneRepository ( ) . setURI ( url ) . setDirectory ( target ) . call ( ) ;
try
{
2015-09-02 07:32:27 +10:00
StoredConfig config = result . getRepository ( ) . getConfig ( ) ;
config . setBoolean ( " core " , null , " autocrlf " , autocrlf ) ;
config . save ( ) ;
2014-11-26 16:56:48 +11:00
2015-09-02 07:32:27 +10:00
System . out . println ( " Cloned git repository " + url + " to " + target . getAbsolutePath ( ) + " . Current HEAD: " + commitHash ( result ) ) ;
2014-11-26 16:56:48 +11:00
} finally
{
result . close ( ) ;
}
}
public static String commitHash ( Git repo ) throws GitAPIException
{
return Iterables . getOnlyElement ( repo . log ( ) . setMaxCount ( 1 ) . call ( ) ) . getName ( ) ;
}
2019-03-25 21:30:02 +11:00
public static File download ( String url , File target , HashFormat hashFormat , String goodHash ) throws IOException
2014-11-26 16:56:48 +11:00
{
System . out . println ( " Starting download of " + url ) ;
byte [ ] bytes = Resources . toByteArray ( new URL ( url ) ) ;
2019-03-25 21:30:02 +11:00
String hash = hashFormat . getHash ( ) . hashBytes ( bytes ) . toString ( ) ;
2014-11-26 16:56:48 +11:00
2019-03-25 21:30:02 +11:00
System . out . println ( " Downloaded file: " + target + " with hash: " + hash ) ;
if ( ! dev & & goodHash ! = null & & ! goodHash . equals ( hash ) )
{
throw new IllegalStateException ( " Downloaded file: " + target + " did not match expected hash: " + goodHash ) ;
}
2014-11-26 16:56:48 +11:00
Files . write ( bytes , target ) ;
return target ;
}
2014-12-08 01:41:20 +02:00
2014-12-12 11:21:43 +11:00
public static void disableHttpsCertificateCheck ( )
{
2014-12-08 01:41:20 +02:00
// This globally disables certificate checking
// http://stackoverflow.com/questions/19723415/java-overriding-function-to-disable-ssl-certificate-check
try
{
2014-12-12 11:21:43 +11:00
TrustManager [ ] trustAllCerts = new TrustManager [ ]
{
new X509TrustManager ( )
{
@Override
public java . security . cert . X509Certificate [ ] getAcceptedIssuers ( )
{
return null ;
}
@Override
public void checkClientTrusted ( X509Certificate [ ] certs , String authType )
{
}
@Override
public void checkServerTrusted ( X509Certificate [ ] certs , String authType )
{
}
2014-12-08 01:41:20 +02:00
}
} ;
2014-12-12 11:21:43 +11:00
// Trust SSL certs
SSLContext sc = SSLContext . getInstance ( " SSL " ) ;
sc . init ( null , trustAllCerts , new SecureRandom ( ) ) ;
HttpsURLConnection . setDefaultSSLSocketFactory ( sc . getSocketFactory ( ) ) ;
// Trust host names
HostnameVerifier allHostsValid = new HostnameVerifier ( )
{
@Override
public boolean verify ( String hostname , SSLSession session )
{
2014-12-08 01:41:20 +02:00
return true ;
}
} ;
2014-12-12 11:21:43 +11:00
HttpsURLConnection . setDefaultHostnameVerifier ( allHostsValid ) ;
2014-12-08 01:41:20 +02:00
} catch ( NoSuchAlgorithmException ex )
{
2014-12-12 11:21:43 +11:00
System . out . println ( " Failed to disable https certificate check " ) ;
ex . printStackTrace ( System . err ) ;
2014-12-08 01:41:20 +02:00
} catch ( KeyManagementException ex )
{
2014-12-12 11:21:43 +11:00
System . out . println ( " Failed to disable https certificate check " ) ;
ex . printStackTrace ( System . err ) ;
}
}
public static void logOutput ( )
{
try
{
final OutputStream logOut = new BufferedOutputStream ( new FileOutputStream ( LOG_FILE ) ) ;
Runtime . getRuntime ( ) . addShutdownHook ( new Thread ( )
{
@Override
public void run ( )
{
System . setOut ( new PrintStream ( new FileOutputStream ( FileDescriptor . out ) ) ) ;
System . setErr ( new PrintStream ( new FileOutputStream ( FileDescriptor . err ) ) ) ;
try
{
logOut . close ( ) ;
} catch ( IOException ex )
{
// We're shutting the jvm down anyway.
}
}
} ) ;
System . setOut ( new PrintStream ( new TeeOutputStream ( System . out , logOut ) ) ) ;
System . setErr ( new PrintStream ( new TeeOutputStream ( System . err , logOut ) ) ) ;
} catch ( FileNotFoundException ex )
{
System . err . println ( " Failed to create log file: " + LOG_FILE ) ;
2014-12-08 01:41:20 +02:00
}
}
2019-03-25 21:30:02 +11:00
public enum HashFormat
{
MD5
{
@Override
public HashFunction getHash ( )
{
return Hashing . md5 ( ) ;
}
} , SHA256
{
@Override
public HashFunction getHash ( )
{
return Hashing . sha256 ( ) ;
}
} , SHA512
{
@Override
public HashFunction getHash ( )
{
return Hashing . sha512 ( ) ;
}
} ;
public abstract HashFunction getHash ( ) ;
}
2014-11-26 16:56:48 +11:00
}