package net.knarcraft.minecraftserverlauncher.utility; import net.knarcraft.minecraftserverlauncher.Main; import net.knarcraft.minecraftserverlauncher.profile.ServerLauncherController; import net.knarcraft.minecraftserverlauncher.server.ServerVersionContainer; import net.knarcraft.minecraftserverlauncher.userinterface.GUI; import net.knarcraft.minecraftserverlauncher.userinterface.ServerLauncherGUI; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.nio.file.Paths; /** * The jar builder is responsible for building the newest Spigot and CraftBukkit .jar files using BuildTools */ public class JarBuilder { private final String buildDirectory; private final String jarDirectory; private final ServerVersionContainer versionContainer; private final GUI gui; private final String javaCommand; /** * Instantiates a new jar builder * * @param buildDirectory
The directory containing BuildTool files
* @param jarDirectoryThe directory containing downloaded .jar files
* @param guiThe GUI to write messages to
*/ public JarBuilder(String buildDirectory, String jarDirectory, GUI gui) { this.buildDirectory = buildDirectory; this.jarDirectory = jarDirectory; this.gui = gui; this.versionContainer = ServerVersionContainer.getInstance(); this.javaCommand = ServerLauncherController.getInstance().getJavaCommand(); try { CommonFunctions.createFolder(new File(buildDirectory)); } catch (FileNotFoundException e) { e.printStackTrace(); } } /** * Builds the latest version of the spigot .jar file */ public boolean buildSpigotJar() { gui.setStatus("Building Spigot jar ..."); downloadBuildTools(); ProcessBuilder processBuilder = new ProcessBuilder(javaCommand, "-jar", "BuildTools.jar", "--rev", "latest", "--output-dir", jarDirectory); if (executeBuildProcess(processBuilder) && moveBuiltJar("spigot-", "SpigotLatest.jar")) { gui.setStatus("Finished moving spigot.jar"); return true; } else { return false; } } /** * Builds the latest version of the craftbukkit .jar file */ public boolean buildBukkitJar() { gui.setStatus("Building Bukkit jar ..."); downloadBuildTools(); ProcessBuilder processBuilder = new ProcessBuilder(javaCommand, "-jar", "BuildTools.jar", "--compile", "craftbukkit", "--rev", "latest", "--output-dir", jarDirectory); if (executeBuildProcess(processBuilder) && moveBuiltJar("craftbukkit-", "BukkitLatest.jar")) { gui.setStatus("Finished moving craftbukkit.jar"); return true; } else { return false; } } /** * Downloads the latest BuildTools version */ public void downloadBuildTools() { ServerLauncherGUI gui = Main.getController().getGUI(); try { String latestVersion = getLatestBuildToolsVersion(); boolean exists = new File(buildDirectory + "BuildTools.jar").exists(); boolean isUpdated = latestVersion.equals(versionContainer.getDownloadedBuildToolsVersion()); if (!exists || !isUpdated) { String buildToolsURL = "https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar"; boolean success = CommonFunctions.downloadFile(buildToolsURL, Paths.get(buildDirectory + "BuildTools.jar")); if (!success) { gui.setStatus("Unable to download the latest BuildTools"); gui.logError("Target: " + buildDirectory + "BuildTools.jar"); gui.logError("URL: " + buildToolsURL); } else { versionContainer.setDownloadedBuildToolsVersion(latestVersion); } } } catch (IOException e) { gui.setStatus("Unable to download the latest BuildTools"); gui.logMessage(e.getMessage()); } } /** * Moves a built .jar file to its target file * * @param searchStringThe start of the name of the built file used to find it
* @param newNameThe new name of the built file
* @returnTrue if the .jar file was moved successfully
*/ private boolean moveBuiltJar(String searchString, String newName) { File[] foundFiles = new File(jarDirectory).listFiles((file) -> file.isFile() && file.getName().startsWith(searchString)); if (foundFiles != null && foundFiles.length == 1) { File newFileLocation = new File(jarDirectory + File.separator + newName); if (newFileLocation.exists()) { if (!newFileLocation.delete()) { gui.showError("Unable to delete previously built .jar"); } } if (!foundFiles[0].renameTo(newFileLocation)) { gui.showError("Unable to move built .jar"); } else { return true; } } return false; } /** * Starts the build process and initializes * * @param processBuilderThe process builder to execute
* @returnTrue if the process exited successfully
*/ private boolean executeBuildProcess(ProcessBuilder processBuilder) { processBuilder.directory(new File(buildDirectory)); processBuilder.redirectErrorStream(true); try { Process process = processBuilder.start(); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); do { writer.write(CommonFunctions.readBufferedReader(reader)); } while (process.isAlive()); writer.newLine(); writer.flush(); if (process.exitValue() == 0) { gui.setStatus("Jar building process finished successfully."); return true; } else { gui.showError("Jar building process failed with exit code " + process.exitValue() + ". Please check the BuildTools log for errors."); } } catch (IOException e) { e.printStackTrace(); } return false; } /** * Gets the latest build tools version available * * @returnThe latest build tools version available
* @throws IOExceptionIf unable to read the version file
*/ String getLatestBuildToolsVersion() throws IOException { String versionDocument; versionDocument = CommonFunctions.readRemoteFile("https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/"); return CommonFunctions.stringBetween(versionDocument, "BuildTools #", " ["); } }