diff --git a/src/main/java/com/seibel/lod/core/JarMain.java b/src/main/java/com/seibel/lod/core/JarMain.java index 922979a39..deaea4a86 100644 --- a/src/main/java/com/seibel/lod/core/JarMain.java +++ b/src/main/java/com/seibel/lod/core/JarMain.java @@ -7,10 +7,13 @@ import com.seibel.lod.core.jar.DarkModeDetector; import com.seibel.lod.core.jar.BaseJFrame; import com.seibel.lod.core.jar.installer.GitlabGetter; import com.seibel.lod.core.jar.JarDependencySetup; +import com.seibel.lod.core.jar.installer.WebDownloader; import javax.swing.*; import java.io.*; +import java.net.URL; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.Locale; /** @@ -20,7 +23,7 @@ import java.util.Locale; */ public class JarMain { public static final boolean isDarkTheme = DarkModeDetector.isDarkMode(); - public static boolean isOffline = GitlabGetter.netIsAvailable(); + public static boolean isOffline = WebDownloader.netIsAvailable(); public static void main(String[] args) { // Sets up the local @@ -37,30 +40,103 @@ public class JarMain { JarDependencySetup.createInitialBindings(); SingletonHandler.finishBinding(); + GitlabGetter.init(); System.out.println("WARNING: The standalone jar still work in progress"); // JOptionPane.showMessageDialog(null, "The GUI for the standalone jar isn't made yet\nIf you want to use the mod then put it in your mods folder", "Distant Horizons", JOptionPane.WARNING_MESSAGE); - if (!getOperatingSystem().equals(OperatingSystem.LINUX)) { - System.out.println("If you want the installer then please use linux for the time being.\nWindows and MacOS support will come later on"); + if (getOperatingSystem().equals(OperatingSystem.MACOS)) { + System.out.println("If you want the installer then please use Linux or for the time being.\nMacOS support/testing will come later on"); } + // All code beyond this point is messy and will be rewritten later as I dont like it + // =============================================================================================================== + BaseJFrame frame = new BaseJFrame(false, false).addExtraButtons(); - String[] optionsToChoose = {"Apple", "Orange", "Banana", "Pineapple"}; - JComboBox jTest = new JComboBox<>(optionsToChoose); - jTest.setBounds(400, 250, 140, 20); - frame.add(jTest); - jTest.addActionListener(e -> { System.out.println("test"); }); +// String[] optionsToChoose = {"Apple", "Orange", "Banana", "Pineapple"}; +// JComboBox jTest = new JComboBox<>(optionsToChoose); +// jTest.setBounds(400, 250, 140, 20); +// frame.add(jTest); +// jTest.addActionListener(e -> { System.out.println("test"); }); + JFileChooser minecraftDirPop = new JFileChooser(); + if (getOperatingSystem().equals(OperatingSystem.WINDOWS)) + minecraftDirPop.setCurrentDirectory(new File(System.getenv("APPDATA")+"/.minecraft/mods")); + if (getOperatingSystem().equals(OperatingSystem.LINUX)) + minecraftDirPop.setCurrentDirectory(new File(System.getProperty("user.home")+"/.minecraft/mods")); + minecraftDirPop.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + JButton minecraftDirBtn = new JButton("Click to select install path"); + minecraftDirBtn.addActionListener(e -> { + if (minecraftDirPop.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION) + minecraftDirBtn.setText(minecraftDirPop.getSelectedFile().toString()); + }); + minecraftDirBtn.setBounds(frame.getWidth()/2 - (200/2), 250, 200, 20); + frame.add(minecraftDirBtn); + + JComboBox modVersions = new JComboBox<>( + Arrays.copyOf(GitlabGetter.readableReleaseNames.toArray(), GitlabGetter.readableReleaseNames.toArray().length, String[].class) + ); + modVersions.setBounds(frame.getWidth()/2 - (200/2), 280, 200, 20); + + JComboBox modMcVersion = new JComboBox<>(); + modMcVersion.setBounds(frame.getWidth()/2 - (200/2), 310, 200, 20); + modMcVersion.setModel( new DefaultComboBoxModel( + Arrays.copyOf( + GitlabGetter.getMcVersionsInRelease(GitlabGetter.releaseNames.get(modVersions.getSelectedIndex())).toArray(), + GitlabGetter.getMcVersionsInRelease(GitlabGetter.releaseNames.get(modVersions.getSelectedIndex())).toArray().length, + String[].class + )) + ); + + modVersions.addActionListener( e -> { + modMcVersion.setModel( new DefaultComboBoxModel( + Arrays.copyOf( + GitlabGetter.getMcVersionsInRelease(GitlabGetter.releaseNames.get(modVersions.getSelectedIndex())).toArray(), + GitlabGetter.getMcVersionsInRelease(GitlabGetter.releaseNames.get(modVersions.getSelectedIndex())).toArray().length, + String[].class + )) + ); + frame.validate(); + }); + frame.add(modVersions); + frame.add(modMcVersion); - System.out.println(GitlabGetter.downloadAsString("https://gitlab.com/api/v4/projects/18204078/releases")); // Fabric installer // try { -// GitlabGetter.downloadAsFile("https://maven.fabricmc.net/net/fabricmc/fabric-installer/0.11.0/fabric-installer-0.11.0.jar", new File(System.getProperty("java.io.tmpdir") + "/fabricInstaller.jar")); +// WebDownloader.downloadAsFile(new URL("https://maven.fabricmc.net/net/fabricmc/fabric-installer/0.11.0/fabric-installer-0.11.0.jar"), new File(System.getProperty("java.io.tmpdir") + "/fabricInstaller.jar")); // Runtime.getRuntime().exec("java -jar " + System.getProperty("java.io.tmpdir") + "/fabricInstaller.jar"); // } catch (Exception e) {e.printStackTrace();} + JButton installMod = new JButton("Install "+ModInfo.READABLE_NAME); + installMod.setBounds(frame.getWidth()/2 - (200/2), 340, 200, 20); + installMod.addActionListener( e -> { + if (minecraftDirPop.getSelectedFile() == null) { + JOptionPane.showMessageDialog(frame, "Please select your install directory", ModInfo.READABLE_NAME, JOptionPane.WARNING_MESSAGE); + return; + } + +// JOptionPane.showMessageDialog(frame, "Installing "+ModInfo.READABLE_NAME+" version "+modVersions.getSelectedItem()+" for Minecraft version "+modMcVersion.getSelectedItem()+" \nAt "+minecraftDirPop.getSelectedFile(), ModInfo.READABLE_NAME, JOptionPane.INFORMATION_MESSAGE); + + URL downloadPath = GitlabGetter.getRelease( + GitlabGetter.releaseNames.get(modVersions.getSelectedIndex()), + (String) modMcVersion.getSelectedItem()); + try { + if (downloadPath.toString().contains("curseforge.com")) + downloadPath = new URL(downloadPath.toString() + "/file"); + } catch (Exception f) { f.printStackTrace(); } + + if (!WebDownloader.downloadAsFile( + downloadPath, + minecraftDirPop.getSelectedFile().toPath().resolve( + ModInfo.NAME+"-"+GitlabGetter.releaseNames.get(modVersions.getSelectedIndex())+"-"+((String) modMcVersion.getSelectedItem())+".jar" + ).toFile() + )) + JOptionPane.showMessageDialog(frame, "Download failed. Check your internet connection", ModInfo.READABLE_NAME, JOptionPane.ERROR_MESSAGE); + else + JOptionPane.showMessageDialog(frame, "Installation done. \nYou can now close the installer", ModInfo.READABLE_NAME, JOptionPane.INFORMATION_MESSAGE); + }); + frame.add(installMod); frame.addLogo(); @@ -70,8 +146,9 @@ public class JarMain { - public enum OperatingSystem {WINDOWS, MACOS, LINUX, NONE} - public static OperatingSystem getOperatingSystem() { + + public enum OperatingSystem {WINDOWS, MACOS, LINUX, NONE} // Easy to use enum for the 3 main os's + public static OperatingSystem getOperatingSystem() { // Get the os and turn it into that enum String os = System.getProperty("os.name").toLowerCase(); if (os.contains("win")) { return OperatingSystem.WINDOWS; diff --git a/src/main/java/com/seibel/lod/core/jar/BaseJFrame.java b/src/main/java/com/seibel/lod/core/jar/BaseJFrame.java index 058fc1b29..c2e659da0 100644 --- a/src/main/java/com/seibel/lod/core/jar/BaseJFrame.java +++ b/src/main/java/com/seibel/lod/core/jar/BaseJFrame.java @@ -21,6 +21,10 @@ import java.nio.charset.StandardCharsets; import java.util.*; import java.util.List; +/** + * @author coolGi + */ +// This will be removed later on to make a better ui public class BaseJFrame extends JFrame { public BaseJFrame() { init(); diff --git a/src/main/java/com/seibel/lod/core/jar/installer/GitlabGetter.java b/src/main/java/com/seibel/lod/core/jar/installer/GitlabGetter.java index ec7dc2595..f73a7bd55 100644 --- a/src/main/java/com/seibel/lod/core/jar/installer/GitlabGetter.java +++ b/src/main/java/com/seibel/lod/core/jar/installer/GitlabGetter.java @@ -1,85 +1,121 @@ package com.seibel.lod.core.jar.installer; +import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; -import javax.net.ssl.HttpsURLConnection; -import javax.swing.*; -import java.io.*; -import java.net.MalformedURLException; import java.net.URL; -import java.net.URLConnection; +import java.util.ArrayList; +import java.util.List; +/** + * Gets the releases available on gitlab and sends out the link + * + * @author coolGi + */ public class GitlabGetter { public static final String GitLabApi = "https://gitlab.com/api/v4/projects/"; public static final String projectID = "18204078"; + public static JSONArray projectRelease = new JSONArray(); + + public static List releaseNames = new ArrayList<>(); // This list contains the release ID's + public static List readableReleaseNames = new ArrayList<>(); // This list contains the readable names of the ID's + private static List mcVersionReleases = new ArrayList<>(); // A list of all minecraft releases + - public static JSONObject projectReleases = new JSONObject(); public static void init() { try { - projectReleases = (JSONObject) new JSONParser().parse(downloadAsString(GitLabApi+projectID+"/releases")); + projectRelease = (JSONArray) new JSONParser().parse(WebDownloader.downloadAsString(new URL(GitLabApi+projectID+"/releases"))); + for (int i = 0; i < projectRelease.size(); i++) { + releaseNames.add(((JSONObject) projectRelease.get(i)).get("tag_name").toString()); + readableReleaseNames.add(((JSONObject) projectRelease.get(i)).get("name").toString()); + } + + // Some tests for getting the release versions +// System.out.println(getRelease("1.6.3a", "1.18.2")); +// System.out.println(getRelease("1.16.4-a1.2", null)); // The oldest downloadable version is 1.2 as versions before that didn't include downloads + + // Set the mcVersionReleases + JSONArray minecraftReleases = (JSONArray) ((JSONObject) new JSONParser().parse(WebDownloader.downloadAsString(new URL("https://launchermeta.mojang.com/mc/game/version_manifest.json")))).get("versions"); + for (int i = 0; i < minecraftReleases.size(); i++) { + JSONObject jsonObject = (JSONObject) minecraftReleases.get(i); + if (jsonObject.get("type").toString().equals("release")) + mcVersionReleases.add(jsonObject.get("id").toString()); + } + + // Some tests to get minecraft versions available in that version of the mod +// System.out.println(getMcVersionsInRelease("1.6.5a")); +// System.out.println(getMcVersionsInRelease("1.16.4-a1.2")); } catch (Exception e) { e.printStackTrace(); } } + /** Gets the compatible minecraft versions a release of the mod works with */ + public static List getMcVersionsInRelease(String version) { + List versions = new ArrayList<>(); - public static boolean netIsAvailable() { + JSONArray releaseArray = null; try { - final URL url = new URL("https://gitlab.com"); - final URLConnection conn = url.openConnection(); - conn.connect(); - conn.getInputStream().close(); - return true; - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } catch (IOException e) { - return false; + releaseArray = ( + ((JSONArray) + ((JSONObject) + ((JSONObject) + projectRelease.get(releaseNames.indexOf(version)) + ).get("assets") + ).get("links"))); + } catch (Exception e) { + System.out.println("ERROR: Release ["+version+"] is not a valid release. Printing stacktrace..."); + e.printStackTrace(); + return null; } - } - public static void downloadAsFile(String urlS, File file) { - try { - URL url = new URL(urlS); - HttpsURLConnection connection = (HttpsURLConnection) url - .openConnection(); - long filesize = connection.getContentLengthLong(); - if (filesize == -1) { - throw new Exception("Content length must not be -1 (unknown)!"); - } - long totalDataRead = 0; - try (java.io.BufferedInputStream in = new java.io.BufferedInputStream( - connection.getInputStream())) { - java.io.FileOutputStream fos = new java.io.FileOutputStream(file); - try (java.io.BufferedOutputStream bout = new BufferedOutputStream( - fos, 1024)) { - byte[] data = new byte[1024]; - int i; - while ((i = in.read(data, 0, 1024)) >= 0) { - totalDataRead = totalDataRead + i; - bout.write(data, 0, i); -// int percent = (int) ((totalDataRead * 100) / filesize); -// System.out.println(percent); - } + for (int i = 0; i < releaseArray.size(); i++) { + String name = ((JSONObject) releaseArray.get(i)).get("name").toString(); + for (String mcVersion : mcVersionReleases) { + if (name.contains(mcVersion)) { + versions.add(mcVersion); + break; } } - } catch (Exception e) { e.printStackTrace(); } + } + + return versions; } - - public static String downloadAsString(String urlS) { - StringBuilder stringBuilder = new StringBuilder(); + /** Gets the url to the download of a release of the mod */ + public static URL getRelease(String version, String mcVersion) { + // Get the asset links of the releases + JSONArray releaseArray = null; try { - URL url = new URL(urlS); - URLConnection urlConnection = url.openConnection(); - urlConnection.setConnectTimeout(1000); - urlConnection.setReadTimeout(1000); - BufferedReader bReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream())); + releaseArray = ( + ((JSONArray) + ((JSONObject) + ((JSONObject) + projectRelease.get(releaseNames.indexOf(version)) + ).get("assets") + ).get("links"))); + } catch (Exception e) { + System.out.println("ERROR: Release ["+version+"] is not a valid release. Printing stacktrace..."); + e.printStackTrace(); + return null; + } - String line; - while ((line = bReader.readLine()) != null) { - stringBuilder.append(line); + + if (mcVersion != null) { + for (int i = 0; i < releaseArray.size(); i++) { + if (((JSONObject) releaseArray.get(i)).get("name").toString().contains(mcVersion)) { // With the way our GitLab releases is set up, the only way to check the mc version is to check if it is in the name + try { + return new URL(((JSONObject) releaseArray.get(i)).get("direct_asset_url").toString()); + } catch (Exception e) { e.printStackTrace(); } + } } - } catch (Exception e) { e.printStackTrace(); } - return (stringBuilder.toString()); + } else { + // If version is null it gets the first version available + try { + return new URL(((JSONObject) releaseArray.get(0)).get("direct_asset_url").toString()); + } catch (Exception e) { e.printStackTrace(); } + } + + return null; } } diff --git a/src/main/java/com/seibel/lod/core/jar/installer/WebDownloader.java b/src/main/java/com/seibel/lod/core/jar/installer/WebDownloader.java new file mode 100644 index 000000000..5d78afd52 --- /dev/null +++ b/src/main/java/com/seibel/lod/core/jar/installer/WebDownloader.java @@ -0,0 +1,82 @@ +package com.seibel.lod.core.jar.installer; + +import javax.net.ssl.HttpsURLConnection; +import java.io.*; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; + +/** + * Does something simmilar to wget + * It allows you to download a file from a link + * + * @author coolGi + */ +public class WebDownloader { + public static boolean netIsAvailable() { + try { + final URL url = new URL("https://gitlab.com"); + final URLConnection conn = url.openConnection(); + conn.connect(); + conn.getInputStream().close(); + return true; + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } catch (IOException e) { + return false; + } + } + + public static boolean downloadAsFile(URL url, File file) { + try { +// URL url = new URL(urlS); + HttpsURLConnection connection = (HttpsURLConnection) url + .openConnection(); + long filesize = connection.getContentLengthLong(); + if (filesize == -1) { + throw new Exception("Content length must not be -1 (unknown)!"); + } + long totalDataRead = 0; + try (java.io.BufferedInputStream in = new java.io.BufferedInputStream( + connection.getInputStream())) { + java.io.FileOutputStream fos = new java.io.FileOutputStream(file); + try (java.io.BufferedOutputStream bout = new BufferedOutputStream( + fos, 1024)) { + byte[] data = new byte[1024]; + int i; + while ((i = in.read(data, 0, 1024)) >= 0) { + totalDataRead = totalDataRead + i; + bout.write(data, 0, i); +// int percent = (int) ((totalDataRead * 100) / filesize); +// System.out.println(percent); + } + } + } + } catch (Exception e) { + System.out.println("WARNING: Failed to download file from "+url); + e.printStackTrace(); + return false; + } + return true; + } + + public static String downloadAsString(URL url) { + StringBuilder stringBuilder = new StringBuilder(); + try { +// URL url = new URL(urlS); + URLConnection urlConnection = url.openConnection(); + urlConnection.setConnectTimeout(1000); + urlConnection.setReadTimeout(1000); + BufferedReader bReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream())); + + String line; + while ((line = bReader.readLine()) != null) { + stringBuilder.append(line); + } + } catch (Exception e) { + System.out.println("WARNING: Failed to download file from "+url); + e.printStackTrace(); + } + return (stringBuilder.toString()); + } +}