package co.forsaken.projectindigo.utils; import java.awt.Desktop; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import javax.swing.JOptionPane; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import co.forsaken.projectindigo.IndigoLauncher; import co.forsaken.projectindigo.Main; import co.forsaken.projectindigo.log.LogManager; import co.forsaken.projectindigo.utils.Utils.OS; public class AutoUpdater { public static void main(String[] args) { if (shouldUpdate()) { if (JOptionPane.showConfirmDialog(null, "An update to the launcher was found! Would you like to download?") == JOptionPane.OK_OPTION) { if (downloadNew()) { LogManager.info("Download done."); relaunch(); System.exit(0); return; } } else { try { goToPage(); } catch (IOException e) {} } } new IndigoLauncher((args.length == 1 ? args[0] : "")); } private static void relaunch() { String javaDir = System.getProperty("java.home") + "/bin/java"; String classpath = System.getProperty("java.class.path"); String className = Main.class.getCanonicalName(); try { new ProcessBuilder(javaDir, "-cp", classpath, className).start(); } catch (IOException e) { e.printStackTrace(); } } private static int parseVersion(String version) { Pattern pat = Pattern.compile("\\."); Matcher match = pat.matcher(version); if (match.find()) { version = match.replaceAll(""); } return Integer.parseInt(version); } public static boolean shouldUpdate() { try { URL url = new URL("https://raw.github.com/ForsakenDev/ProjectIndigo/master/pom.xml"); URLConnection connection = url.openConnection(); Document doc = parseXML(connection.getInputStream()); NodeList descNodes = doc.getElementsByTagName("project"); String version = (String) ((Element) descNodes.item(0)).getElementsByTagName("version").item(0).getChildNodes().item(0).getNodeValue(); InputStream pomStream = AutoUpdater.class.getClassLoader().getResourceAsStream("META-INF/maven/co.forsaken/projectindigo/pom.xml"); if (pomStream != null) { doc = parseXML(pomStream); descNodes = doc.getElementsByTagName("project"); String clientVersion = (String) ((Element) descNodes.item(0)).getElementsByTagName("version").item(0).getChildNodes().item(0).getNodeValue(); return parseVersion(version) > parseVersion(clientVersion); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (ParserConfigurationException e) { e.printStackTrace(); } return false; } private static Document parseXML(InputStream stream) throws SAXException, IOException, ParserConfigurationException { DocumentBuilderFactory objDocumentBuilderFactory = null; DocumentBuilder objDocumentBuilder = null; objDocumentBuilderFactory = DocumentBuilderFactory.newInstance(); objDocumentBuilder = objDocumentBuilderFactory.newDocumentBuilder(); return (Document) objDocumentBuilder.parse(stream); } private static boolean downloadNew() { try { String jarLocation = AutoUpdater.class.getProtectionDomain().getCodeSource().getLocation().getPath(); URL url = new URL("http://indigo.forsaken.co/downloads/jar/ProjectIndigo.jar"); if (Utils.getCurrentOS() == OS.WINDOWS && jarLocation.contains(".exe")) { url = new URL("http://indigo.forsaken.co/downloads/exe/ProjectIndigo.exe"); jarLocation = jarLocation.substring(0, jarLocation.indexOf(".exe") + 4); } else if (Utils.getCurrentOS() == OS.MACOSX && jarLocation.contains(".app")) { url = new URL("http://indigo.forsaken.co/downloads/app/ProjectIndigo.zip"); jarLocation = jarLocation.substring(0, jarLocation.indexOf(".app") + 4); } HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.addRequestProperty("User-Agent", "Mozilla/4.76"); File file = new File(jarLocation); FileUtils.deleteDirectory(file); LogManager.info("Update detected. Attempting to download."); InputStream input = connection.getInputStream(); saveStreamToFileAndUnZip(input, file); input.close(); return true; } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return false; } public static void goToPage() throws IOException { JOptionPane.showMessageDialog(null, "You might experience issues using an outdated version, check the website for information"); if (Desktop.isDesktopSupported()) { try { Desktop.getDesktop().browse(new URI("http://indigo.forsaken.co/")); } catch (URISyntaxException e) { e.printStackTrace(); } } } public static void saveStreamToFileAndUnZip(InputStream input, File file) throws IOException { OutputStream output = new FileOutputStream(file); byte[] buffer = new byte[1024]; int read; while ((read = input.read(buffer)) > 0) { output.write(buffer, 0, read); } output.close(); if (file.getAbsolutePath().contains(".zip")) { File parentDir = file.getParentFile(); ZipInputStream zipIn = null; try { input = new FileInputStream(file); zipIn = new ZipInputStream(input); ZipEntry currentEntry = zipIn.getNextEntry(); while (currentEntry != null) { if (currentEntry.getName().contains("META-INF") || currentEntry.getName().contains("__MACOSX") || currentEntry.getName().contains(".DS_Store")) { currentEntry = zipIn.getNextEntry(); continue; } if (currentEntry.isDirectory()) { File tmp = new File(parentDir, currentEntry.getName()); if (!tmp.exists()) { tmp.mkdir(); } currentEntry = zipIn.getNextEntry(); continue; } FileOutputStream outStream = new FileOutputStream(new File(parentDir, currentEntry.getName())); int readLen; buffer = new byte[1024]; while ((readLen = zipIn.read(buffer, 0, buffer.length)) > 0) { outStream.write(buffer, 0, readLen); } outStream.close(); currentEntry = zipIn.getNextEntry(); } } catch (IOException e) { LogManager.error(e.getMessage()); } finally { try { zipIn.close(); input.close(); } catch (IOException e) { LogManager.error(e.getMessage()); } } file.delete(); } } }