From 26cc5370e22ecfbb40910f741421dd167a49e3ec Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 6 Aug 2020 19:55:27 +0200 Subject: [PATCH] Does some much needed cleanup, adds the Paper server type and fixes broken downloads --- .../minecraftserverlauncher/Main.java | 26 +- .../profile/Collection.java | 67 +- .../profile/Profile.java | 327 +------ .../server/AdvancedServerType.java | 65 -- .../server/Server.java | 204 +---- .../server/ServerType.java | 134 --- .../server/ServerTypeHandler.java | 136 +++ .../servertypes/AbstractServerType.java | 51 ++ .../server/servertypes/BungeeCord.java | 41 + .../server/servertypes/CraftBukkit.java | 33 + .../server/servertypes/Custom.java | 23 + .../server/servertypes/MCPCPlus.java | 17 + .../server/servertypes/Paper.java | 17 + .../server/servertypes/ServerType.java | 30 + .../server/servertypes/Snapshot.java | 18 + .../server/servertypes/Spigot.java | 17 + .../server/servertypes/SpongeVanilla.java | 53 ++ .../server/servertypes/Travertine.java | 4 + .../server/servertypes/Vanilla.java | 102 +++ .../server/servertypes/Waterfall.java | 4 + .../userinterface/GUI.java | 792 +---------------- .../userinterface/MessageHandler.java | 61 ++ .../userinterface/ServerLauncherGUI.java | 811 ++++++++++++++++++ .../userinterface/ServerTab.java | 22 +- .../CommonFunctions.java} | 109 ++- .../utility/JarDownloader.java | 68 ++ src/main/resources/servertypes.csv | 11 +- .../DownloadTests.java | 12 +- .../minecraftserverlauncher/Tests.java | 8 +- .../userinterface/FakeGUI.java | 16 + 30 files changed, 1722 insertions(+), 1557 deletions(-) delete mode 100644 src/main/java/net/knarcraft/minecraftserverlauncher/server/AdvancedServerType.java delete mode 100644 src/main/java/net/knarcraft/minecraftserverlauncher/server/ServerType.java create mode 100644 src/main/java/net/knarcraft/minecraftserverlauncher/server/ServerTypeHandler.java create mode 100644 src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/AbstractServerType.java create mode 100644 src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/BungeeCord.java create mode 100644 src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/CraftBukkit.java create mode 100644 src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Custom.java create mode 100644 src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/MCPCPlus.java create mode 100644 src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Paper.java create mode 100644 src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/ServerType.java create mode 100644 src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Snapshot.java create mode 100644 src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Spigot.java create mode 100644 src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/SpongeVanilla.java create mode 100644 src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Travertine.java create mode 100644 src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Vanilla.java create mode 100644 src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Waterfall.java create mode 100644 src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/MessageHandler.java create mode 100644 src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherGUI.java rename src/main/java/net/knarcraft/minecraftserverlauncher/{Shared.java => utility/CommonFunctions.java} (50%) create mode 100644 src/main/java/net/knarcraft/minecraftserverlauncher/utility/JarDownloader.java create mode 100644 src/test/java/net/knarcraft/minecraftserverlauncher/userinterface/FakeGUI.java diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java b/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java index e2d65db..f598bf4 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java @@ -7,10 +7,9 @@ import com.google.gson.JsonParser; import net.knarcraft.minecraftserverlauncher.profile.Collection; import net.knarcraft.minecraftserverlauncher.profile.Profile; import net.knarcraft.minecraftserverlauncher.server.Server; -import net.knarcraft.minecraftserverlauncher.server.ServerType; +import net.knarcraft.minecraftserverlauncher.userinterface.GUI; import net.knarcraft.minecraftserverlauncher.userinterface.ServerConsoles; -import javax.naming.ConfigurationException; import javax.swing.*; import java.awt.*; import java.io.*; @@ -20,7 +19,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import static net.knarcraft.minecraftserverlauncher.Shared.*; +import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.*; //Java 8 required. /** @@ -36,6 +35,7 @@ public class Main { private static boolean serversAreRunning = false; private static final String updateChannel = "alpha"; private static final String updateURL = "https://api.knarcraft.net/minecraftserverlauncher"; + private static GUI gui; public static void main(String[] args) throws IOException { checkForUpdate(); @@ -46,9 +46,9 @@ public class Main { } EventQueue.invokeLater(() -> { try { - setup(); new ServerConsoles(); Profile.load(); + gui = Profile.getGUI(); ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor(); exec.scheduleAtFixedRate(Main::updateConsoles, 10, 500, TimeUnit.MILLISECONDS); } catch (Exception e) { @@ -57,18 +57,6 @@ public class Main { }); } - /** - * Loads all server types, so that they are ready for use - */ - private static void setup() { - try { - ServerType.loadServerTypes(); - } catch (ConfigurationException e) { - e.printStackTrace(); - System.exit(1); - } - } - /** * Retrieves the directory the .jar file is running from * @@ -217,7 +205,7 @@ public class Main { if (downloadFile(url, new File(dir + "update.jar").toPath())) { doUpdate(dir); } else { - Profile.showError("Update available", + gui.showError("Update available", "An update is available, but could not be downloaded."); } } @@ -236,7 +224,7 @@ public class Main { if (new File(dir + "update.jar").renameTo(new File (dir + "Minecraft-Server-Launcher.jar"))) { if (new File(dir + "Old.jar").delete()) { - Profile.showMessage("Update complete", + gui.showMessage("Update complete", "Update finished. Please run the software again."); System.exit(0); } @@ -247,7 +235,7 @@ public class Main { } } } - Profile.showError("Update failed", + gui.showError("Update failed", "Could not replace the main .jar with the downloaded .jar."); } } diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Collection.java b/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Collection.java index b0ea6c8..4f69182 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Collection.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Collection.java @@ -1,16 +1,18 @@ package net.knarcraft.minecraftserverlauncher.profile; -import net.knarcraft.minecraftserverlauncher.userinterface.ServerTab; import net.knarcraft.minecraftserverlauncher.server.Server; -import net.knarcraft.minecraftserverlauncher.userinterface.ServerConsoles; import net.knarcraft.minecraftserverlauncher.userinterface.Console; +import net.knarcraft.minecraftserverlauncher.userinterface.ServerConsoles; +import net.knarcraft.minecraftserverlauncher.userinterface.ServerTab; + +import javax.naming.ConfigurationException; /** * Acts as a wrapper for objects necessary for each server. * - * @author Kristian Knarvik - * @version 1.0.0 - * @since 1.0.0 + * @author Kristian Knarvik + * @version 1.0.0 + * @since 1.0.0 */ public class Collection { private final Server server; @@ -20,9 +22,10 @@ public class Collection { /** * Creates a new collection with the given name + * * @param name

The name identifying the server, server tab, collection and server console

*/ - Collection(String name) { + Collection(String name) throws ConfigurationException { this.serverTab = new ServerTab(name); this.server = new Server(name); this.serverConsole = ServerConsoles.addConsoleTab(name); @@ -31,41 +34,23 @@ public class Collection { /** * Creates a new collection with the given parameters - * @param name

The name identifying the server, server tab, collection and server console

- * @param serverPath

The path of the server folder

- * @param enabled

Whether the server should be run when starting servers

- * @param typeName

The name of the server type the server uses

- * @param serverVersion

The version of the running server type.

- * @param maxRam

The maximum amount of RAM the server is allowed to use.

- * @param vanillaVersion

The currently selected vanilla version

- * @param snapshotVersion

The currently selected snapshot version

+ * + * @param name

The name identifying the server, server tab, collection and server console

+ * @param serverPath

The path of the server folder

+ * @param enabled

Whether the server should be run when starting servers

+ * @param typeName

The name of the server type the server uses

+ * @param serverVersion

The version of the running server type.

+ * @param maxRam

The maximum amount of RAM the server is allowed to use.

+ * @param vanillaVersion

The currently selected vanilla version

+ * @param snapshotVersion

The currently selected snapshot version

* @param spongeVanillaVersion

The currently selected SpongeVanilla version

- * @param bungeeVersion

The currently selected Bungee version

+ * @param bungeeVersion

The currently selected Bungee version

*/ - Collection(String name, - String serverPath, - boolean enabled, - String typeName, - String serverVersion, - String maxRam, - String vanillaVersion, - String snapshotVersion, - String spongeVanillaVersion, - String bungeeVersion - ) { + Collection(String name, String serverPath, boolean enabled, String typeName, String serverVersion, String maxRam, + String vanillaVersion, String snapshotVersion, String spongeVanillaVersion, String bungeeVersion) throws ConfigurationException { this.serverTab = new ServerTab(name); - this.server = new Server( - name, - serverPath, - enabled, - typeName, - serverVersion, - maxRam, - vanillaVersion, - snapshotVersion, - spongeVanillaVersion, - bungeeVersion - ); + this.server = new Server(name, serverPath, enabled, typeName, serverVersion, maxRam, vanillaVersion, + snapshotVersion, spongeVanillaVersion, bungeeVersion); this.serverConsole = ServerConsoles.addConsoleTab(name); this.name = name; this.serverTab.setData(serverPath, enabled, typeName, serverVersion, maxRam); @@ -73,6 +58,7 @@ public class Collection { /** * Gets the name of the collection + * * @return

Collection name

*/ public String getName() { @@ -81,6 +67,7 @@ public class Collection { /** * Gets the server of the collection + * * @return

Collection server

*/ public Server getServer() { @@ -89,14 +76,16 @@ public class Collection { /** * Gets the server tab of the collection + * * @return

Collection server tab

*/ public ServerTab getServerTab() { - return this.serverTab; + return this.serverTab; } /** * Gets the server console of the collection + * * @return

Collection server console

*/ public Console getServerConsole() { diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Profile.java b/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Profile.java index 22a4353..976a608 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Profile.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Profile.java @@ -1,30 +1,21 @@ package net.knarcraft.minecraftserverlauncher.profile; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import net.knarcraft.minecraftserverlauncher.userinterface.GUI; +import net.knarcraft.minecraftserverlauncher.server.ServerTypeHandler; +import net.knarcraft.minecraftserverlauncher.userinterface.ServerLauncherGUI; import net.knarcraft.minecraftserverlauncher.userinterface.ServerConsoles; import net.knarcraft.minecraftserverlauncher.userinterface.ServerTab; -import net.knarcraft.minecraftserverlauncher.server.AdvancedServerType; import net.knarcraft.minecraftserverlauncher.server.Server; -import net.knarcraft.minecraftserverlauncher.server.ServerType; import net.knarcraft.minecraftserverlauncher.Main; +import net.knarcraft.minecraftserverlauncher.utility.JarDownloader; +import javax.naming.ConfigurationException; import javax.swing.*; import java.io.*; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.NoSuchElementException; -import java.util.Objects; import java.util.Scanner; import java.util.concurrent.Executors; -import static net.knarcraft.minecraftserverlauncher.Shared.downloadFile; -import static net.knarcraft.minecraftserverlauncher.Shared.readFile; -import static net.knarcraft.minecraftserverlauncher.Shared.stringBetween; - /** * Contains all user settings, and a list of servers. * @@ -35,7 +26,7 @@ import static net.knarcraft.minecraftserverlauncher.Shared.stringBetween; public class Profile { private static final ArrayList profiles = new ArrayList<>(); private static Profile current; - private static GUI gui; + private static ServerLauncherGUI serverLauncherGui; private static final String profilesDir = Main.getApplicationWorkDirectory() + File.separator + "files"; private static final String profilesFile = Main.getApplicationWorkDirectory() + File.separator + "files" + File.separator + "Profiles.txt"; private static final String jarDirectory = Main.getApplicationWorkDirectory() + File.separator + "files" + File.separator + "Jars" + File.separator; @@ -73,8 +64,8 @@ public class Profile { } } - public static GUI getGUI() { - return gui; + public static ServerLauncherGUI getGUI() { + return serverLauncherGui; } public boolean getRunInBackground() { @@ -162,7 +153,7 @@ public class Profile { * * @param name The name of the collection and its elements. */ - public void addCollection(String name) { + public void addCollection(String name) throws ConfigurationException { if (name == null) { //If a user cancels or crosses out window return; } @@ -175,7 +166,7 @@ public class Profile { ) { collections.add(new Collection(name)); } else { - showError("A server name must my unique and not empty or \"All\"." + + serverLauncherGui.showError("A server name must my unique and not empty or \"All\"." + "It can't contain any of the characters \"!\", \"?\" or \";\"."); } } @@ -190,12 +181,12 @@ public class Profile { return; } if (name.equals("") && !name.matches("^[!?;]+$")) { - showError("Profile name can't be blank."); + serverLauncherGui.showError("Profile name can't be blank."); return; } for (Profile profile : profiles) { if (profile.name.equals(name)) { - showError("There is already a profile with this name."); + serverLauncherGui.showError("There is already a profile with this name."); return; } } @@ -206,7 +197,7 @@ public class Profile { for (int i = 0; i < collections.size(); i++) { if (collections.get(i).getName().equals(name)) { this.collections.remove(i); - gui.update(); + serverLauncherGui.update(); break; } } @@ -242,7 +233,7 @@ public class Profile { try { collection.getServer().sendCommand(command); } catch (IOException e) { - showError("Server " + collection.getName() + " caused an exception."); + serverLauncherGui.showError("Server " + collection.getName() + " caused an exception."); } } } else { @@ -252,10 +243,10 @@ public class Profile { try { target.sendCommand(command); } catch (IOException e) { - showError("Server " + target.getName() + " caused an exception."); + serverLauncherGui.showError("Server " + target.getName() + " caused an exception."); } } else { - showError("Server " + serverName + " is invalid."); + serverLauncherGui.showError("Server " + serverName + " is invalid."); } } } @@ -270,27 +261,27 @@ public class Profile { ServerTab serverTab = collection.getServerTab(); server.setPath(serverTab.getPath()); server.setMaxRam(serverTab.getMaxRam()); - server.setType(ServerType.getByName(serverTab.getType())); + server.setType(ServerTypeHandler.getByName(serverTab.getType())); try { server.setServerVersion(serverTab.getVersion()); } catch (IllegalArgumentException e) { - showError("Invalid server version for " + server.getName()); + serverLauncherGui.showError("Invalid server version for " + server.getName()); } server.toggle(serverTab.enabled()); } if (!new File(profilesDir).exists() && !new File(profilesDir).mkdirs()) { - showError("Unable to create the folder " + profilesDir); + serverLauncherGui.showError("Unable to create the folder " + profilesDir); throw new FileNotFoundException("Unable to create the profiles folder: " + profilesDir); } try (PrintWriter file = new PrintWriter(profilesFile)) { int width; int height; - if (gui == null) { + if (serverLauncherGui == null) { width = 440; height = 170; } else { - width = gui.getSize().width; - height = gui.getSize().height; + width = serverLauncherGui.getSize().width; + height = serverLauncherGui.getSize().height; } file.println(String.format( "%s;%s;%s;%s;%d;%d", @@ -334,8 +325,8 @@ public class Profile { ))) { fileAppend.println(saveString); } catch (IOException e) { - if (gui != null) { - showError("Unable to save to file. Try running the software as an administrator."); + if (serverLauncherGui != null) { + serverLauncherGui.showError("Unable to save to file. Try running the software as an administrator."); } else { System.out.println("Unable to save to file. Try running the software as an administrator."); } @@ -343,8 +334,8 @@ public class Profile { } } } catch (IOException e) { - if (gui != null) { - showError("Unable to save to file. Try running the software as an administrator."); + if (serverLauncherGui != null) { + serverLauncherGui.showError("Unable to save to file. Try running the software as an administrator."); } throw new FileNotFoundException("Unable to create the profiles file"); } @@ -353,7 +344,7 @@ public class Profile { /** * Reads profiles and servers from a text file. */ - public static void load() { + public static void load() throws ConfigurationException { try (Scanner in = new Scanner(new File(profilesFile))) { try { String[] staticData = in.nextLine().split(";", -1); @@ -363,7 +354,7 @@ public class Profile { bungeeVersion = staticData[3]; int guiWidth = Integer.parseInt(staticData[4]); int guiHeight = Integer.parseInt(staticData[5]); - gui = new GUI(guiWidth, guiHeight); + serverLauncherGui = new ServerLauncherGUI(guiWidth, guiHeight); while (in.hasNextLine()) { String line = in.nextLine(); if (line.contains("?")) { @@ -388,7 +379,7 @@ public class Profile { current = getProfile(profileName); } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) { e.printStackTrace(); - showError("Invalid Profile.txt file. Profiles could not be loaded. If this error persists, please " + + serverLauncherGui.showError("Invalid Profile.txt file. Profiles could not be loaded. If this error persists, please " + "manually delete the file."); System.exit(1); } catch (IOException e) { @@ -398,23 +389,24 @@ public class Profile { addProfile("Default"); } } catch (FileNotFoundException | NoSuchElementException e) { - showMessage("A profiles file was not found. Default profile was created."); + serverLauncherGui.showMessage("A profiles file was not found. Default profile was created."); try { - gui = new GUI(); + serverLauncherGui = new ServerLauncherGUI(); } catch (FileNotFoundException ex) { - showMessage("Failed to load GUI messages. The GUI can't be shown."); + serverLauncherGui.showMessage("Failed to load ServerLauncherGUI messages. The ServerLauncherGUI can't be shown."); } catch (IOException ex) { ex.printStackTrace(); } addProfile("Default"); } - gui.update(); - gui.updateProfiles(); + serverLauncherGui.update(); + serverLauncherGui.updateProfiles(); current.updateConsoles(); if (current.downloadAllAvailableJARFiles) { Executors.newSingleThreadExecutor().execute(() -> { + JarDownloader downloader = new JarDownloader(serverLauncherGui, jarDirectory); try { - downloadJars(); + downloader.downloadJars(); } catch (IOException e) { e.printStackTrace(); } @@ -422,7 +414,7 @@ public class Profile { } if (current.runInBackground) { Executors.newSingleThreadExecutor().execute(Server::startServers); - gui.hide(); + serverLauncherGui.hide(); } } @@ -445,7 +437,7 @@ public class Profile { * @param profile

The profile which to add the collection

* @param serverData

The data to parse

*/ - private static void parseServer(Profile profile, String[] serverData) { + private static void parseServer(Profile profile, String[] serverData) throws ConfigurationException { profile.collections.add(new Collection( serverData[0], serverData[1], @@ -459,249 +451,4 @@ public class Profile { serverData[9]) ); } - - /** - * Downloads all jars to the program directory. - * - * @throws IOException On version file failure or folder creation failure - */ - public static void downloadJars() throws IOException { - if (!new File(jarDirectory).exists() && !new File(jarDirectory).mkdirs()) { - showError("Could not create the Jars folder. Please run the program with admin permissions, or move it to " + - "a writable directory."); - throw new FileNotFoundException("Unable to create jars folder"); - } - try { - downloadAll(); - printToGui("Finished downloading jars"); - } catch (FileNotFoundException e) { - throw new FileNotFoundException("One or more downloads failed: " + e.getMessage()); - } - } - - /** - * Prints something to the gui status field if the gui exists - * Otherwise it prints to the console - * @param message

The string to show the user

- */ - private static void printToGui(String message) { - if (gui != null) { - gui.setStatus(message); - } else { - System.out.println(message); - } - } - - public static void showError(String title, String message) { - if (gui != null) { - JOptionPane.showMessageDialog( - null, - message, - title, - JOptionPane.ERROR_MESSAGE - ); - } else { - System.out.println(message); - } - } - - public static void showError(String message) { - if (gui != null) { - JOptionPane.showMessageDialog( - null, - message, - "Error", - JOptionPane.ERROR_MESSAGE - ); - } else { - System.out.println(message); - } - } - - public static void showMessage(String title, String message) { - if (gui != null) { - JOptionPane.showMessageDialog( - null, - message, - title, - JOptionPane.INFORMATION_MESSAGE - ); - } else { - System.out.println(message); - } - } - - public static void showMessage(String message) { - if (gui != null) { - JOptionPane.showMessageDialog( - null, - message, - "Info", - JOptionPane.INFORMATION_MESSAGE - ); - } else { - System.out.println(message); - } - } - - private static void showMessage() {} - - /** - * Downloads jar files for all possible server versions - * @throws IOException

If a jar fails to download

- */ - private static void downloadAll() throws IOException { - for (ServerType type : ServerType.getServerTypes()) { - String downloadURL = Objects.requireNonNull(type).getDownloadURL(); - String typeName = type.getName(); - AdvancedServerType advancedServerType = type instanceof AdvancedServerType ? (AdvancedServerType) type : null; - for (String version : type.getVersions()) { - boolean success; - printToGui("Downloading: " + typeName + version + ".jar"); - File file = new File(jarDirectory + type.getName() + version + ".jar"); - Path filePath = Paths.get(jarDirectory + type.getName() + version + ".jar"); - switch (type.getName()) { - case "Vanilla": - case "Snapshot": - success = downloadVanillaJar(advancedServerType, file, downloadURL, filePath, typeName, version); - break; - case "Spigot": - case "Craftbukkit": - case "MCPCplus": - success = downloadSpigotJar(file, downloadURL, typeName, version, filePath); - break; - case "SpongeVanilla": - success = downloadSpongeVanillaJar(advancedServerType, file, downloadURL, filePath, version); - break; - case "Bungee": - success = downloadBungeeJar(advancedServerType, file, downloadURL, filePath, typeName); - break; - default: - success = true; - } - if (!success) { - printToGui("Error downloading: " + typeName + version + ".jar"); - throw new FileNotFoundException("Error downloading: " + typeName + version + ".jar"); - } - } - } - } - - /** - * Downloads a Spigot, Craftbukkit or MCPC+ .jar file - * @param file

The file the .jar file should be saved as

- * @param downloadURL

The base URL for downloading the .jar file

- * @param typeName

The name of the selected server type

- * @param version

The version of the .jar file to download

- * @param filePath

The path of the .jar file

- * @return

True if the file exists or the file was successfully downloaded

- */ - private static boolean downloadSpigotJar(File file, String downloadURL, String typeName, String version, Path filePath) { - return file.isFile() || downloadFile(downloadURL + typeName + version + ".jar", filePath); - } - - /** - * Downloads a Vanilla/Snapshot .jar file according to the input - * @param advancedServerType

The advanced server type containing required information

- * @param file

The file the .jar file should be saved as

- * @param downloadURL

The base URL for downloading the .jar file

- * @param filePath

The path of the .jar file

- * @param typeName

The name of the selected server type

- * @param version

The version of the .jar file to download

- * @return

True if the file exists or the file was successfully downloaded

- * @throws IOException

If something goes horribly wrong

- */ - private static boolean downloadVanillaJar(AdvancedServerType advancedServerType, File file, String downloadURL, - Path filePath, String typeName, String version) throws IOException { - if (version.equals("Latest")) { - String versionText = readFile(Objects.requireNonNull(advancedServerType).getVersionURL()); - JsonObject jsonObject = new JsonParser().parse(versionText).getAsJsonObject(); - String latest = jsonObject.getAsJsonObject("latest").get("release").getAsString(); - JsonElement ver = jsonObject.getAsJsonArray("versions").get(0); - String versionFile = ver.getAsJsonObject().get("url").getAsString(); - versionText = readFile(versionFile); - jsonObject = new JsonParser().parse(versionText).getAsJsonObject(); - String jarFile = jsonObject.getAsJsonObject("downloads").getAsJsonObject("server").get("url").getAsString(); - setVersion(typeName, latest); - return (file.isFile() && latest.equals(getVersion(typeName))) || downloadFile(jarFile, filePath); - } else { - return file.isFile() || downloadFile(downloadURL + version + - Objects.requireNonNull(advancedServerType).getDownloadURLPart() + version + ".jar", filePath); - } - } - - /** - * Downloads a SpongeVanilla .jar file according to the input - * @param advancedServerType

The advanced server type containing required information

- * @param file

The file the .jar file should be saved as

- * @param downloadURL

The base URL for downloading the .jar file

- * @param filePath

The path of the .jar file

- * @param version

The version of the .jar file to download

- * @return

True if the file exists or the file was successfully downloaded

- * @throws IOException

If something goes horribly wrong

- */ - private static boolean downloadSpongeVanillaJar(AdvancedServerType advancedServerType, File file, - String downloadURL, Path filePath, - String version) throws IOException { - String newestVersion = stringBetween(readFile(Objects.requireNonNull(advancedServerType).getVersionURL() - + version), advancedServerType.getSrcStart(), advancedServerType.getSrcEnd()); - return file.isFile() || downloadFile(downloadURL + newestVersion + advancedServerType.getDownloadURLPart() - + newestVersion + ".jar", filePath); - } - - /** - * Downloads a Bungee .jar file according to the input - * @param advancedServerType

The advanced server type containing required information

- * @param file

The file the .jar file should be saved as

- * @param downloadURL

The base URL for downloading the .jar file

- * @param filePath

The path of the .jar file

- * @param typeName

The name of the selected server type

- * @return

True if the file exists or the file was successfully downloaded

- * @throws IOException

If something goes horribly wrong

- */ - private static boolean downloadBungeeJar(AdvancedServerType advancedServerType, File file, - String downloadURL, Path filePath, String typeName) throws IOException { - String newestVersion = stringBetween(readFile(Objects.requireNonNull(advancedServerType).getVersionURL()), - advancedServerType.getSrcStart(), advancedServerType.getSrcEnd()); - setVersion(typeName, newestVersion); - return (file.isFile() && newestVersion.equals(getVersion(typeName))) || downloadFile(downloadURL, filePath); - } - - /** - * Returns the current version of a type - * @param type

The version type

- * @return

The version string

- */ - private static String getVersion(String type) { - switch (type) { - case "Vanilla": - return vanillaVersion; - case "Snapshot": - return snapshotVersion; - case "Bungee": - return bungeeVersion; - default: - return ""; - } - } - - /** - * Sets a server type's last downloaded version - * @param type

The version type

- * @param version

The version string

- */ - private static void setVersion(String type, String version) { - if (!type.equals("")) { - switch (type) { - case "Vanilla": - vanillaVersion = version; - break; - case "Snapshot": - snapshotVersion = version; - break; - case "Bungee": - bungeeVersion = version; - } - } - } } diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/AdvancedServerType.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/AdvancedServerType.java deleted file mode 100644 index 78c2b39..0000000 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/server/AdvancedServerType.java +++ /dev/null @@ -1,65 +0,0 @@ -package net.knarcraft.minecraftserverlauncher.server; - -/** - * A more advanced servertype for particularly tricky jar downloads. - * - * @author Kristian Knarvik - * @version 1.0.0 - * @since 1.0.0 - */ -public class AdvancedServerType extends ServerType { - private final String versionURL; - private final String downloadURLPart; - private final String srcStart; - private final String srcEnd; - - /** - * Instantiates a new Advanced server type - * @param name

The name of the server type

- * @param versions

A list of one or more server versions for the type

- * @param versionURL

The URL for checking last version for server type

- * @param srcStart

The string in the version file marking the start of the newest version entry

- * @param srcEnd

The string in the version file marking the end of the newest version entry

- * @param downloadURL

The URL used for downloading .jar files

- * @param downloadURLPart

An extra part for the download URL

- */ - AdvancedServerType(String name, String[] versions, String versionURL, String srcStart, String srcEnd, String downloadURL, String downloadURLPart) { - super(name, versions, downloadURL); - this.srcStart = srcStart; - this.srcEnd = srcEnd; - this.versionURL = versionURL; - this.downloadURLPart = downloadURLPart; - } - - /** - * Gets the URL used for downloading latest version information - * @return

The latest version URL

- */ - public String getVersionURL() { - return this.versionURL; - } - - /** - * Gets an additional part of the download URL - * @return

Additional download URL part

- */ - public String getDownloadURLPart() { - return this.downloadURLPart; - } - - /** - * Gets the string marking the start of the latest server version in the version document - * @return

A string marking the start of the latest version

- */ - public String getSrcStart() { - return this.srcStart; - } - - /** - * Gets the string marking the end of the latest server version in the version document - * @return

A string marking the end of the latest version

- */ - public String getSrcEnd() { - return this.srcEnd; - } -} diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java index 02c84e7..0a5d638 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java @@ -1,16 +1,17 @@ package net.knarcraft.minecraftserverlauncher.server; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import net.knarcraft.minecraftserverlauncher.Shared; +import net.knarcraft.minecraftserverlauncher.Main; import net.knarcraft.minecraftserverlauncher.profile.Collection; import net.knarcraft.minecraftserverlauncher.profile.Profile; -import net.knarcraft.minecraftserverlauncher.Main; +import net.knarcraft.minecraftserverlauncher.server.servertypes.ServerType; -import java.io.*; -import java.nio.file.Path; -import java.nio.file.Paths; +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.util.ArrayList; import java.util.concurrent.TimeUnit; @@ -18,14 +19,16 @@ import java.util.concurrent.TimeUnit; /** * Contains all necessary information to create, run and manage a Minecraft server. * - * @author Kristian Knarvik - * @version 1.0.0 - * @since 1.0.0 + * @author Kristian Knarvik + * @version 1.0.0 + * @since 1.0.0 */ public class Server { - /** Available ram sizes. For GUI dropdown */ + /** + * Available ram sizes. For ServerLauncherGUI dropdown + */ private static final String[] ramList = { - "512M", "1G", "2G", "3G", "4G", "5G", "6G", "7G", "8G", "9G", "10G","11G", "12G", "13G", "14G", "15G", "16G" + "512M", "1G", "2G", "3G", "4G", "5G", "6G", "7G", "8G", "9G", "10G", "11G", "12G", "13G", "14G", "15G", "16G" }; private static final String jarDirectory = Main.getApplicationWorkDirectory() + File.separator + "files" + File.separator + "Jars" + File.separator; @@ -39,10 +42,10 @@ public class Server { private Process process; private BufferedWriter writer; private BufferedReader reader; - private String vanillaVersion; - private String snapshotVersion; - private String spongeVanillaVersion; - private String bungeeVersion; + private final String vanillaVersion; + private final String snapshotVersion; + private final String spongeVanillaVersion; + private final String bungeeVersion; private boolean started; public Server(String name) { @@ -62,22 +65,12 @@ public class Server { this.bungeeVersion = ""; } - public Server( - String name, - String path, - boolean enabled, - String typeName, - String serverVersion, - String maxRam, - String vanillaVersion, - String snapshotVersion, - String spongeVanillaVersion, - String bungeeVersion - ) { + public Server(String name, String path, boolean enabled, String typeName, String serverVersion, String maxRam, + String vanillaVersion, String snapshotVersion, String spongeVanillaVersion, String bungeeVersion) { this.name = name; this.path = path; this.enabled = enabled; - this.type = ServerType.getByName(typeName); + this.type = ServerTypeHandler.getByName(typeName); this.serverVersion = serverVersion; this.maxRam = maxRam; this.vanillaVersion = vanillaVersion; @@ -147,13 +140,13 @@ public class Server { } /** - * @return A representation of the name of a jarfile. + * @return A representation of the name of a jarfile. */ private String getType() { if (this.type.getName().equals("Custom")) { return this.serverVersion; } else { - return this.type.getName() + this.serverVersion + ".jar"; + return ""; } } @@ -182,7 +175,7 @@ public class Server { /** * Removes a player with the selected name from the playerlist. * - * @param name The name of the player to remove + * @param name The name of the player to remove */ public void removePlayer(String name) { playerList.removeIf(player -> player.equals(name)); @@ -224,7 +217,7 @@ public class Server { /** * Tries to stop all enabled servers. * - * @throws IOException If a writer's process is already closed but not null. + * @throws IOException If a writer's process is already closed but not null. */ public static void stop() throws IOException { for (Collection collection : Profile.getCurrent().getCollections()) { @@ -272,7 +265,7 @@ public class Server { Profile.getGUI().setStatus("Downloading jar..."); this.downloadJar(); Profile.getGUI().setStatus("File downloaded"); - } catch (FileNotFoundException e) { + } catch (IOException e) { System.out.println(e.getMessage()); Profile.getGUI().setStatus("Error: Jar file not found"); e.printStackTrace(); @@ -293,7 +286,7 @@ public class Server { String serverPath; if (Profile.getCurrent().getDownloadAllAvailableJARFiles() && !type.getName().equals("Custom")) { serverPath = jarDirectory + this.getType(); - } else { + } else { serverPath = this.path + File.separator + this.getType(); } builder = new ProcessBuilder( @@ -310,7 +303,7 @@ public class Server { builder.redirectErrorStream(true); this.process = builder.start(); this.writer = new BufferedWriter(new OutputStreamWriter(this.process.getOutputStream())); - this.reader = new BufferedReader (new InputStreamReader(this.process.getInputStream())); + this.reader = new BufferedReader(new InputStreamReader(this.process.getInputStream())); Profile.getGUI().setStatus("Servers are running"); this.started = true; return true; @@ -328,8 +321,8 @@ public class Server { /** * Reads all available output from the server process. * - * @return The server output - * @throws IOException If reading from the reader fails + * @return The server output + * @throws IOException If reading from the reader fails */ public String read() throws IOException { String line; @@ -343,139 +336,20 @@ public class Server { /** * Downloads necessary .jar file for the server. * This is unfortunately hardcoded since there is no golden standard, and we only host some jars ourselves. + * * @throws FileNotFoundException if the file was not found and could not be acquired. */ - private void downloadJar() throws FileNotFoundException { - AdvancedServerType type; - File file = new File(this.path + File.separator + this.getType()); - Path filePath = Paths.get(this.path + File.separator + this.getType()); - String versionText, newestVersion, url = this.type.getDownloadURL(), name = this.type.getName(), ver = this.serverVersion; - switch (this.type.getName()) { - case "Custom": - if (!file.isFile()) { - throw new FileNotFoundException("Specified custom jar was not found."); - } - break; - case "Spigot": - case "Craftbukkit": - case "MCPCplus": - if (!(file.isFile() || Shared.downloadFile(url + name + ver + ".jar", filePath))) { - throw new FileNotFoundException("Jar file could not be downloaded."); - } - break; - case "Vanilla": - case "Snapshot": - type = (AdvancedServerType) this.type; - if (this.serverVersion.equals("Latest")) { - try { - versionText = Shared.readFile(type.getVersionURL()); - } catch (IOException e) { - throw new FileNotFoundException("Version file could not be downloaded."); - } - JsonObject jsonObject = new JsonParser().parse(versionText).getAsJsonObject(); - String latest = jsonObject.getAsJsonObject("latest").get("release").getAsString(); - JsonElement verElem = jsonObject.getAsJsonArray("versions").get(0); - String versionFile = verElem.getAsJsonObject().get("url").getAsString(); - - try { - versionText = Shared.readFile(versionFile); - } catch (IOException e) { - throw new FileNotFoundException("Version file could not be downloaded."); - } - - if (!file.isFile() || !latest.equals(this.getVersion(name))) { - this.setVersion(name, latest); - - jsonObject = new JsonParser().parse(versionText).getAsJsonObject(); - String jarFile = jsonObject.getAsJsonObject("downloads").getAsJsonObject("server").get("url").getAsString(); - - if (!Shared.downloadFile(jarFile, filePath)) { - throw new FileNotFoundException("Jar file could not be downloaded."); - } - } - } else { - if (!(file.isFile() || Shared.downloadFile(url + ver + type.getDownloadURLPart() + ver + ".jar", filePath))) { - throw new FileNotFoundException("Jar file could not be downloaded."); - } - } - break; - case "SpongeVanilla": - type = (AdvancedServerType) this.type; - try { - versionText = Shared.readFile(type.getVersionURL() + this.serverVersion); - } catch (IOException e) { - throw new FileNotFoundException("Version file could not be downloaded."); - } - newestVersion = Shared.stringBetween(versionText, type.getSrcStart(), type.getSrcEnd()); - if (!file.isFile() || !newestVersion.equals(this.getVersion(name))) { - this.setVersion(name, newestVersion); - if (!Shared.downloadFile(url + newestVersion + type.getDownloadURLPart() + newestVersion + ".jar", filePath)) { - throw new FileNotFoundException("Jar file could not be downloaded."); - } - } - break; - case "Bungee": - type = (AdvancedServerType) this.type; - try { - versionText = Shared.readFile(type.getVersionURL()); - } catch (IOException e) { - throw new FileNotFoundException("Version file could not be downloaded."); - } - newestVersion = Shared.stringBetween(versionText, type.getSrcStart(), type.getSrcEnd()); - if (!file.isFile() || !newestVersion.equals(this.getVersion(name))) { - this.setVersion(name, newestVersion); - if (!Shared.downloadFile(url, filePath)) { - throw new FileNotFoundException("Jar file could not be downloaded."); - } - } - } - } - - /** - * Returns the current version of a type - * @param type

The version type

- * @return

The version string

- */ - private String getVersion(String type) { - switch (type) { - case "Vanilla": - return this.vanillaVersion; - case "Snapshot": - return this.snapshotVersion; - case "SpongeVanilla": - return this.spongeVanillaVersion; - case "Bungee": - return this.bungeeVersion; - default: - return ""; - } - } - - /** - * Sets a server type's last downloaded version. - * @param type

The version type

- * @param version

The version string

- */ - private void setVersion(String type, String version) { - if (!type.equals("")) { - switch (type) { - case "Vanilla": - this.vanillaVersion = version; - break; - case "Snapshot": - this.snapshotVersion = version; - break; - case "SpongeVanilla": - this.spongeVanillaVersion = version; - break; - case "Bungee": - this.bungeeVersion = version; - } + private void downloadJar() throws IOException { + String path = this.path + File.separator; + File file = new File(path + this.getType()); + if (!(file.isFile() || type.downloadJar(path, this.serverVersion))) { + throw new FileNotFoundException("Jar file could not be downloaded."); } } /** * Sends a command to this server through its writer. + * * @param command

Command to send to the server

* @throws IOException

If write fails

*/ diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/ServerType.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/ServerType.java deleted file mode 100644 index 94637a7..0000000 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/server/ServerType.java +++ /dev/null @@ -1,134 +0,0 @@ -package net.knarcraft.minecraftserverlauncher.server; - -import javax.naming.ConfigurationException; -import java.io.File; -import java.io.FileNotFoundException; -import java.util.ArrayList; -import java.util.Scanner; - -import static net.knarcraft.minecraftserverlauncher.Shared.getResourceAsScanner; - -/** - * Contains the bare minimum to be a functional server type. - * - * @author Kristian Knarvik - * @version 1.0.0 - * @since 1.0.0 - */ -public class ServerType { - private final String name; - private final String[] versions; - private final String downloadURL; - private static final ArrayList serverTypes = new ArrayList<>(); - - /** - * Instantiates a new server type - * @param name

The name of the server type

- * @param versions

A list of one or more server versions for the type

- * @param downloadURL

The URL used for downloading .jar files

- */ - ServerType(String name, String[] versions, String downloadURL) { - this.name = name; - this.versions = versions; - this.downloadURL = downloadURL; - serverTypes.add(this); - } - - /** - * Gets the name of the server type - * @return

Server type name

- */ - public String getName() { - return this.name; - } - - /** - * Gets a list of versions available for the server type - * @return

A list of server versions

- */ - public String[] getVersions() { - return this.versions; - } - - /** - * Gets the url used for downloading JAR files - * @return

A download URL

- */ - public String getDownloadURL() { - return this.downloadURL; - } - - /** - * Gets all instantiated server types - * @return

A list of server types

- */ - public static ArrayList getServerTypes() { - return serverTypes; - } - - /** - * Gets a list of all server types' names. - * @return

A list of strings

- */ - public static String[] getTypeNames() { - ArrayList types = ServerType.getServerTypes(); - String[] serverTypeNames = new String[types.size()]; - for (int i = 0; i < types.size(); i++) { - serverTypeNames[i] = types.get(i).getName(); - } - return serverTypeNames; - } - - /** - * Gets a server type by the given name - * @param name

Then name of the server type

- * @return

A ServerType

- */ - public static ServerType getByName(String name) { - for (ServerType serverType : serverTypes) { - if (serverType.getName().equals(name)) { - return serverType; - } - } - return null; - } - - /** - * Reads valid server types and version from a file, and creates their objects. - * @throws ConfigurationException

If anything goes wrong

- */ - public static void loadServerTypes() throws ConfigurationException { - if (serverTypes.isEmpty()) { - Scanner file; - try { - file = getResourceAsScanner("servertypes.csv"); - } catch (FileNotFoundException e) { - throw new ConfigurationException("Server type configuration file is missing."); - } - while (file.hasNextLine()) { - //Splits the next file line into arguments - String[] fileLine = file.nextLine().split(";", -1); - int lineLength = fileLine.length; - //Gets list of server versions from file line - String[] serverVersion; - if (fileLine[1].contains(",")) { - serverVersion = fileLine[1].split(",", -1); - } else { - serverVersion = new String[]{fileLine[1]}; - } - switch (lineLength) { - case 7: - new AdvancedServerType(fileLine[0], serverVersion, fileLine[2], fileLine[3], fileLine[4], fileLine[5], fileLine[6]); - break; - case 3: - new ServerType(fileLine[0], serverVersion, fileLine[2]); - break; - default: - throw new ConfigurationException("Error: Configuration file invalid."); - } - } - } else { - throw new ConfigurationException("Error: Configuration already loaded."); - } - } -} \ No newline at end of file diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/ServerTypeHandler.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/ServerTypeHandler.java new file mode 100644 index 0000000..66816e0 --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/ServerTypeHandler.java @@ -0,0 +1,136 @@ +package net.knarcraft.minecraftserverlauncher.server; + +import net.knarcraft.minecraftserverlauncher.server.servertypes.BungeeCord; +import net.knarcraft.minecraftserverlauncher.server.servertypes.CraftBukkit; +import net.knarcraft.minecraftserverlauncher.server.servertypes.Custom; +import net.knarcraft.minecraftserverlauncher.server.servertypes.MCPCPlus; +import net.knarcraft.minecraftserverlauncher.server.servertypes.Paper; +import net.knarcraft.minecraftserverlauncher.server.servertypes.ServerType; +import net.knarcraft.minecraftserverlauncher.server.servertypes.Snapshot; +import net.knarcraft.minecraftserverlauncher.server.servertypes.Spigot; +import net.knarcraft.minecraftserverlauncher.server.servertypes.SpongeVanilla; +import net.knarcraft.minecraftserverlauncher.server.servertypes.Vanilla; + +import javax.naming.ConfigurationException; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Scanner; + +import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.getResourceAsScanner; + +/** + * A class which keeps track of available server types + */ +public class ServerTypeHandler { + + private static final ArrayList serverTypes = new ArrayList<>(); + + /** + * Gets a list of all server types' names. + * @return

A list of strings

+ */ + public static String[] getTypeNames() throws ConfigurationException { + ArrayList types = getServerTypes(); + String[] serverTypeNames = new String[types.size()]; + for (int i = 0; i < types.size(); i++) { + serverTypeNames[i] = types.get(i).getName(); + } + return serverTypeNames; + } + + /** + * Gets all instantiated server types + * @return

A list of server types

+ */ + public static ArrayList getServerTypes() throws ConfigurationException { + if (serverTypes.isEmpty()) { + loadServerTypes(); + } + return serverTypes; + } + + /** + * Gets a server type by the given name + * @param name

Then name of the server type

+ * @return

A AbstractServerType

+ */ + public static ServerType getByName(String name) { + for (ServerType serverType : serverTypes) { + if (serverType.getName().equals(name)) { + return serverType; + } + } + return null; + } + + /** + * Reads valid server types and version from a file, and creates their objects. + * @throws ConfigurationException

If anything goes wrong

+ */ + private static void loadServerTypes() throws ConfigurationException { + Scanner file; + try { + file = getResourceAsScanner("servertypes.csv"); + } catch (FileNotFoundException e) { + throw new ConfigurationException("Server type configuration file is missing."); + } + while (file.hasNextLine()) { + //Splits the next file line into arguments + String[] serverTypeInfo = file.nextLine().split(";", -1); + + //Gets list of server versions from file line + String[] serverVersions; + if (serverTypeInfo[1].contains(",")) { + serverVersions = serverTypeInfo[1].split(",", -1); + } else { + serverVersions = new String[]{serverTypeInfo[1]}; + } + + addServerType(serverTypeInfo, serverVersions); + } + } + + /** + * Adds a new server type + * + * @param serverTypeInfo

A list containing necessary information for initializing the server type

+ * @param serverVersions

A list of all server versions for the server type

+ */ + private static void addServerType(String[] serverTypeInfo, String[] serverVersions) { + ServerType newType; + switch (serverTypeInfo[0]) { + case "Craftbukkit": + newType = new CraftBukkit("Bukkit", serverVersions, serverTypeInfo[2], serverTypeInfo[3]); + break; + case "Spigot": + newType = new Spigot("Spigot", serverVersions, serverTypeInfo[2], serverTypeInfo[3]); + break; + case "Vanilla": + newType = new Vanilla("Vanilla", serverVersions, serverTypeInfo[2], serverTypeInfo[3]); + break; + case "Snapshot": + newType = new Snapshot("Snapshot", serverVersions, serverTypeInfo[2], serverTypeInfo[3]); + break; + case "MCPCplus": + newType = new MCPCPlus("MCPCplus", serverVersions, serverTypeInfo[2], serverTypeInfo[3]); + break; + case "Paper": + newType = new Paper("Paper", serverVersions, serverTypeInfo[2], serverTypeInfo[3]); + break; + case "Bungee": + newType = new BungeeCord("Bungee", serverVersions, serverTypeInfo[2], serverTypeInfo[3], + serverTypeInfo[4], serverTypeInfo[5]); + break; + case "SpongeVanilla": + newType = new SpongeVanilla("SpongeVanilla", serverVersions, serverTypeInfo[2], serverTypeInfo[3], + serverTypeInfo[4], serverTypeInfo[5], serverTypeInfo[6]); + break; + case "Custom": + newType = new Custom("Custom", serverVersions, serverTypeInfo[2]); + break; + default: + throw new IllegalArgumentException("Unknown server type defined in config file."); + } + serverTypes.add(newType); + } +} diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/AbstractServerType.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/AbstractServerType.java new file mode 100644 index 0000000..81a32cc --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/AbstractServerType.java @@ -0,0 +1,51 @@ +package net.knarcraft.minecraftserverlauncher.server.servertypes; + +/** + * Contains the bare minimum to be a functional server type. + * + * @author Kristian Knarvik + * @version 1.0.0 + * @since 1.0.0 + */ +public abstract class AbstractServerType implements ServerType { + private final String typeName; + private final String[] versions; + final String downloadURL; + + /** + * Instantiates a new server type + * @param typeName

The typeName of the server type

+ * @param versions

A list of one or more server versions for the type

+ * @param downloadURL

The URL used for downloading .jar files

+ */ + AbstractServerType(String typeName, String[] versions, String downloadURL) { + this.typeName = typeName; + this.versions = versions; + this.downloadURL = downloadURL; + } + + /** + * Gets the name of the server type + * @return

Server type typeName

+ */ + public String getName() { + return this.typeName; + } + + /** + * Gets a list of versions available for the server type + * @return

A list of server versions

+ */ + public String[] getVersions() { + return this.versions; + } + + /** + * Gets the url used for downloading JAR files + * @return

A download URL

+ */ + public String getDownloadURL() { + return this.downloadURL; + } + +} \ No newline at end of file diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/BungeeCord.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/BungeeCord.java new file mode 100644 index 0000000..9a908d3 --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/BungeeCord.java @@ -0,0 +1,41 @@ +package net.knarcraft.minecraftserverlauncher.server.servertypes; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; + +import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.downloadFile; +import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.readFile; +import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.stringBetween; + +public class BungeeCord extends AbstractServerType { + + private String versionURL; + private String lastVersion; + private String srcStart; + private String srcEnd; + + /** + * Instantiates a new server type + * + * @param typeName

The typeName of the server type

+ * @param versions

A list of one or more server versions for the type

+ * @param downloadURL

The URL used for downloading .jar files

+ */ + public BungeeCord(String typeName, String[] versions, String versionURL, String srcStart, String srcEnd, String downloadURL) { + super(typeName, versions, downloadURL); + this.versionURL = versionURL; + this.srcStart = srcStart; + this.srcEnd = srcEnd; + } + + @Override + public boolean downloadJar(String folder, String version) throws IOException { + String file = this.getName() + version + ".jar"; + File filePath = new File(folder + file); + String newestVersion = stringBetween(readFile(versionURL), srcStart, srcEnd); + String oldVersion = lastVersion; + lastVersion = newestVersion; + return (filePath.isFile() && newestVersion.equals(oldVersion)) || downloadFile(downloadURL, Paths.get(filePath.toURI())); + } +} diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/CraftBukkit.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/CraftBukkit.java new file mode 100644 index 0000000..9b69229 --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/CraftBukkit.java @@ -0,0 +1,33 @@ +package net.knarcraft.minecraftserverlauncher.server.servertypes; + +import java.io.File; +import java.nio.file.Paths; + +import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.downloadFile; + +public class CraftBukkit extends AbstractServerType { + + private String downloadURLPart; + + /** + * Instantiates a new server type + * + * @param typeName

The name of the server type

+ * @param versions

A list of one or more server versions for the type

+ * @param downloadURL

The URL used for downloading .jar files

+ * @param downloadURLPart

A string used after the download url as an additional part of the URL

+ */ + public CraftBukkit(String typeName, String[] versions, String downloadURL, String downloadURLPart) { + super(typeName, versions, downloadURL); + this.downloadURLPart = downloadURLPart; + } + + @Override + public boolean downloadJar(String folder, String version) { + String targetFile = this.getName() + version + ".jar"; + String file = downloadURLPart + version + ".jar"; + File filePath = new File(folder + targetFile); + return filePath.isFile() || downloadFile(downloadURL + file, Paths.get(filePath.toURI())); + } + +} diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Custom.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Custom.java new file mode 100644 index 0000000..b1cb748 --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Custom.java @@ -0,0 +1,23 @@ +package net.knarcraft.minecraftserverlauncher.server.servertypes; + +import java.io.File; +import java.io.IOException; + +public class Custom extends AbstractServerType { + /** + * Instantiates a new server type + * + * @param typeName

The name of the server type

+ * @param versions

A list of one or more server versions for the type

+ * @param downloadURL

The URL used for downloading .jar files

+ */ + public Custom(String typeName, String[] versions, String downloadURL) { + super(typeName, versions, downloadURL); + } + + @Override + public boolean downloadJar(String folder, String version) throws IOException { + File filePath = new File(folder + version); + return filePath.isFile(); + } +} diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/MCPCPlus.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/MCPCPlus.java new file mode 100644 index 0000000..a66d64b --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/MCPCPlus.java @@ -0,0 +1,17 @@ +package net.knarcraft.minecraftserverlauncher.server.servertypes; + +public class MCPCPlus extends CraftBukkit { + + /** + * Instantiates a new server type + * + * @param typeName

The name of the server type

+ * @param versions

A list of one or more server versions for the type

+ * @param downloadURL

The URL used for downloading .jar files

+ * @param downloadURLPart

A string used after the download url as an additional part of the URL

+ */ + public MCPCPlus(String typeName, String[] versions, String downloadURL, String downloadURLPart) { + super(typeName, versions, downloadURL, downloadURLPart); + } + +} diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Paper.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Paper.java new file mode 100644 index 0000000..d2c65f9 --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Paper.java @@ -0,0 +1,17 @@ +package net.knarcraft.minecraftserverlauncher.server.servertypes; + +public class Paper extends Spigot { + + /** + * Instantiates a new server type + * + * @param typeName

The typeName of the server type

+ * @param versions

A list of one or more server versions for the type

+ * @param downloadURL

The URL used for downloading .jar files

+ * @param downloadURLPart

A string used after the download url as an additional part of the URL

+ */ + public Paper(String typeName, String[] versions, String downloadURL, String downloadURLPart) { + super(typeName, versions, downloadURL, downloadURLPart); + } + +} diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/ServerType.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/ServerType.java new file mode 100644 index 0000000..1a45191 --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/ServerType.java @@ -0,0 +1,30 @@ +package net.knarcraft.minecraftserverlauncher.server.servertypes; + +import java.io.IOException; + +/** + * Describes a server type + */ +public interface ServerType { + + /** + * Gets the name of the server type + * @return

Server type name

+ */ + String getName(); + + /** + * Gets a list of versions available for the server type + * @return

A list of server versions

+ */ + String[] getVersions(); + + /** + * Downloads a .jar file for this server type + * + * @param folder

The folder to save the downloaded file to

+ * @param version

The server type version to use

+ * @return

True if the file exists or was downloaded

+ */ + boolean downloadJar(String folder, String version) throws IOException; +} diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Snapshot.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Snapshot.java new file mode 100644 index 0000000..755225a --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Snapshot.java @@ -0,0 +1,18 @@ +package net.knarcraft.minecraftserverlauncher.server.servertypes; + +public class Snapshot extends Vanilla { + + /** + * Instantiates a snapshot server type + * + * @param typeName

The name of this server type

+ * @param versions

Available versions for this server type

+ * @param versionURL

The URL used for downloading the version document

+ * @param downloadURL

The URL used for downloading the new file

+ */ + public Snapshot(String typeName, String[] versions, String versionURL, String downloadURL) { + super(typeName, versions, versionURL, downloadURL); + this.releaseType = "snapshot"; + } + +} diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Spigot.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Spigot.java new file mode 100644 index 0000000..21553d3 --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Spigot.java @@ -0,0 +1,17 @@ +package net.knarcraft.minecraftserverlauncher.server.servertypes; + +public class Spigot extends CraftBukkit { + + /** + * Instantiates a new server type + * + * @param typeName

The typeName of the server type

+ * @param versions

A list of one or more server versions for the type

+ * @param downloadURL

The URL used for downloading .jar files

+ * @param downloadURLPart

A string used after the download url as an additional part of the URL

+ */ + public Spigot(String typeName, String[] versions, String downloadURL, String downloadURLPart) { + super(typeName, versions, downloadURL, downloadURLPart); + } + +} diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/SpongeVanilla.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/SpongeVanilla.java new file mode 100644 index 0000000..9533ac4 --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/SpongeVanilla.java @@ -0,0 +1,53 @@ +package net.knarcraft.minecraftserverlauncher.server.servertypes; + +import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; + +import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.downloadFile; + +public class SpongeVanilla extends AbstractServerType { + + private String versionURL; + private String lastVersion; + private String srcStart; + private String srcEnd; + private String downloadURLPart; + + /** + * Instantiates a new SpongeVanilla server type + * + * @param typeName

The name of this server type

+ * @param versions

Available versions for this server type

+ * @param versionURL

The URL used for downloading the version document

+ * @param srcStart

The string to search for to determine newest version

+ * @param srcEnd

The string marking the end of the newest version statement

+ * @param downloadURL

The URL used for downloading the new file

+ * @param downloadURLPart

A string used after the download url as an additional part of the URL

+ */ + public SpongeVanilla(String typeName, String[] versions, String versionURL, String srcStart, String srcEnd, + String downloadURL, String downloadURLPart) { + super(typeName, versions, downloadURL); + this.versionURL = versionURL; + this.srcStart = srcStart; + this.srcEnd = srcEnd; + this.downloadURLPart = downloadURLPart; + } + + @Override + public boolean downloadJar(String folder, String version) throws IOException { + String file = this.getName() + version + ".jar"; + File filePath = new File(folder + file); + + String versionText = CommonFunctions.readFile(versionURL + version); + String newestVersion = CommonFunctions.stringBetween(versionText, srcStart, srcEnd); + + String jarURL = downloadURL + newestVersion + downloadURLPart + newestVersion + ".jar"; + String oldVersion = lastVersion; + lastVersion = newestVersion; + + return (filePath.isFile() && newestVersion.equals(oldVersion)) || downloadFile(jarURL, Paths.get(filePath.toURI())); + } +} diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Travertine.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Travertine.java new file mode 100644 index 0000000..929203b --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Travertine.java @@ -0,0 +1,4 @@ +package net.knarcraft.minecraftserverlauncher.server.servertypes; + +public class Travertine { +} diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Vanilla.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Vanilla.java new file mode 100644 index 0000000..67912d4 --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Vanilla.java @@ -0,0 +1,102 @@ +package net.knarcraft.minecraftserverlauncher.server.servertypes; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Paths; + +import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.downloadFile; +import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.readFile; + +public class Vanilla extends AbstractServerType { + + private final String versionURL; + private String lastVersion; + String releaseType; + + /** + * Instantiates a vanilla server type + * + * @param typeName

The name of this server type to display

+ * @param versions

Available versions for this server type

+ * @param versionURL

The URL used for downloading the version document

+ * @param downloadURL

The URL used for downloading the new file

+ */ + public Vanilla(String typeName, String[] versions, String versionURL, String downloadURL) { + super(typeName, versions, downloadURL); + this.versionURL = versionURL; + this.releaseType = "release"; + } + + @Override + public boolean downloadJar(String folder, String version) throws IOException { + String file = this.getName() + version + ".jar"; + File filePath = new File(folder + file); + if (version.equals("Latest")) { + String[] latestData = getLatestFile(); + String latest = latestData[0]; + String jarFile = latestData[1]; + String currentVersion = lastVersion; + lastVersion = latest; + return (filePath.isFile() && latest.equals(currentVersion)) || downloadFile(jarFile, Paths.get(filePath.toURI())); + } else { + String downloadURL = getVanillaDownloadURL(getServerFileVersionURL(version)); + return filePath.isFile() || downloadFile(downloadURL, Paths.get(filePath.toURI())); + } + } + + /** + * Gets the URL to the .jar file for the newest version + * + * @return

An array containing the latest version and a link to its file

+ * @throws IOException

If the remote resource cannot be read

+ */ + private String[] getLatestFile() throws IOException { + String versionText = readFile(versionURL); + JsonObject jsonObject = new JsonParser().parse(versionText).getAsJsonObject(); + String latest = jsonObject.getAsJsonObject("latest").get(releaseType).getAsString(); + String versionURL = getServerFileVersionURL(latest); + String jarURL = getVanillaDownloadURL(versionURL); + return new String[]{latest, jarURL}; + } + + /** + * Gets the URL necessary for downloading a given minecraft .jar file + * + * @param versionURL

The URL to the version document describing the .jar file

+ * @return

The URL necessary do download the .jar file

+ * @throws IOException

If the remote resource cannot be read

+ */ + private String getVanillaDownloadURL(String versionURL) throws IOException { + String versionText = readFile(versionURL); + JsonObject jsonObject = new JsonParser().parse(versionText).getAsJsonObject(); + return jsonObject.getAsJsonObject("downloads").getAsJsonObject("server").get("url").getAsString(); + } + + /** + * Gets the version URL from the Minecraft vanilla version document + * + * @param targetVersion

The version to download

+ * @return

The URL to the file

+ * @throws IOException

If the file cannot be downloaded

+ */ + private String getServerFileVersionURL(String targetVersion) throws IOException { + String versionText = readFile(versionURL); + JsonObject jsonObject = new JsonParser().parse(versionText).getAsJsonObject(); + JsonArray availableVersions = jsonObject.getAsJsonArray("versions"); + for (JsonElement availableVersion : availableVersions) { + JsonObject versionObject = availableVersion.getAsJsonObject(); + if (!versionObject.get("id").getAsString().equals(targetVersion)) { + continue; + } + return versionObject.get("url").getAsString(); + } + throw new FileNotFoundException("Unable to find the requested Minecraft vanilla .jar file."); + } + +} diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Waterfall.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Waterfall.java new file mode 100644 index 0000000..3c05f9d --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Waterfall.java @@ -0,0 +1,4 @@ +package net.knarcraft.minecraftserverlauncher.server.servertypes; + +public class Waterfall { +} diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/GUI.java b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/GUI.java index 3a79de5..60f49e1 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/GUI.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/GUI.java @@ -1,799 +1,45 @@ package net.knarcraft.minecraftserverlauncher.userinterface; -import net.knarcraft.minecraftserverlauncher.Shared; -import net.knarcraft.minecraftserverlauncher.profile.Collection; -import net.knarcraft.minecraftserverlauncher.Main; -import net.knarcraft.minecraftserverlauncher.server.Server; -import net.knarcraft.minecraftserverlauncher.profile.Profile; - -import javax.imageio.ImageIO; -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import java.io.*; -import java.util.ArrayList; -import java.util.Objects; -import java.util.Scanner; -import java.util.concurrent.Executors; - -import static java.awt.Frame.NORMAL; -import static javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE; -import static net.knarcraft.minecraftserverlauncher.Shared.getResourceAsScanner; -import static net.knarcraft.minecraftserverlauncher.Shared.getResourceAsStream; - /** - * Generates a GUI. - * - * @author Kristian Knarvik - * @version 1.0.0 - * @since 1.0.0 + * Describes a generic GUI */ -public class GUI implements ActionListener { - - private JFrame frame; - private JTabbedPane tabbedPane; - private JTabbedPane serversPane; - //Menu - private JCheckBoxMenuItem chckbxmntmRunInBackground, chckbxmntmDelayStartup, chckbxmntmDownloadJars; //Options - private JMenuItem mntmErrors, mntmSetup, mntmManualUpdate; //Help - private JMenuItem mntmRunInBackground, mntmDelayStartup, mntmDownloadJars; //Info/options - private JMenuItem mntmAbout, mntmStory; //Info/about - //Basic controls - private JButton btnStartServer, btnStopServer, addServer, backup, addProfile, delProfile; - private JComboBox profiles; - private final JLabel lblStatuslabel = new JLabel("Servers are stopped"); - //Server controls - private JComboBox targetServer; - private JComboBox targetPlayer; - private JButton btnKick, btnBan, btnOp, btnDeop, btnCustomCommand, btnSaveserver, btnReload, btnServerConsoles; - private JTextField customCommand; - //Text - private String setupText; - private String runInBackgroundText; - private String delayStartupText; - private String downloadJarsText; - private String aboutText; - - private final ArrayList globalPlayers; - private SystemTray tray; - private TrayIcon trayIcon; +public interface GUI { /** - * Creates the application window - */ - public GUI() throws IOException { - initialize(440, 170); - loadMessages(); - this.globalPlayers = new ArrayList<>(); - } - - /** - * Creates the application window with a preferred width and height - * @param width

The preferred width

- * @param height

The preferred height

- */ - public GUI(int width, int height) throws IOException { - initialize(width, height); - loadMessages(); - this.globalPlayers = new ArrayList<>(); - } - - /** - * Gets the pane used for server configurations + * Displays a message to the user in the GUI message field * - * @return A JTabbedPane + * @param message

The message contents

*/ - public JTabbedPane getPane() { - return this.serversPane; - } + void printMessageToGUI(String message); /** - * Sets the text of the status label. + * Displays an error to the user as an independent box * - * @param text The new text + * @param title

The title of the error message

+ * @param message

The error message contents

*/ - public void setStatus(String text) { - this.lblStatuslabel.setText(text); - try (PrintWriter file = new PrintWriter(new FileWriter(Main.getApplicationWorkDirectory() + File.separator + "latestrun.log", true))) { - file.println(text); - } catch (IOException e ) { - e.printStackTrace(); - } - } + void showError(String title, String message); /** - * Adds a player to the global playerlist, and updates the players combo. + * Displays an error to the user as an independent box * - * @param name The name of the player to add + * @param message

The error message contents

*/ - public void addPlayer(String name) { - this.globalPlayers.add(name); - this.updatePlayers(); - } + void showError(String message); /** - * Removes a player from the global list of players. + * Displays a message to the user as an independent box * - * @param name The name of the player to remove. + * @param title

The title of the message

+ * @param message

The message contents

*/ - public void removePlayer(String name) { - globalPlayers.removeIf(playerName -> playerName.equals(name)); - this.updatePlayers(); - } + void showMessage(String title, String message); /** - * Updates the profiles combo. - */ - public void updateProfiles() { - this.profiles.removeAllItems(); - for (Profile profile : Profile.getProfiles()) { - this.profiles.addItem(profile.getName()); - } - } - - /** - * Gets the size of the main JFrame + * Displays a message to the user as an independent box * - * @return The Dimension of the frame + * @param message

The message contents

*/ - public Dimension getSize() { - return frame.getContentPane().getSize(); - } + void showMessage(String message); - /** - * Updates GUI according to current profile settings. - */ - public void update() { - serversPane.removeAll(); - for (Collection collection : Profile.getCurrent().getCollections()) { - serversPane.addTab(collection.getName(), collection.getServerTab().getPanel()); - } - chckbxmntmRunInBackground.setState(Profile.getCurrent().getRunInBackground()); - chckbxmntmDelayStartup.setState(Profile.getCurrent().getDelayStartup() > 0); - chckbxmntmDownloadJars.setState(Profile.getCurrent().getDownloadAllAvailableJARFiles()); - this.targetServer.removeAllItems(); - this.targetServer.addItem("All"); - for (Collection collection : Profile.getCurrent().getCollections()) { - this.targetServer.addItem(collection.getName()); - } - } - - /** - * Creates the GUI, - */ - private void initialize(int width, int height) throws IOException { - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (ClassNotFoundException | - UnsupportedLookAndFeelException | - InstantiationException | - IllegalAccessException e - ) { - e.printStackTrace(); - } - - frame = new JFrame("Minecraft server launcher"); - frame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); - frame.getContentPane().setPreferredSize(new Dimension(width, height)); - - ImageIcon img = new ImageIcon(ImageIO.read(getResourceAsStream("GUIIcon.png"))); - - frame.setIconImage(img.getImage()); - - JMenuBar menuBar = new JMenuBar(); - frame.setJMenuBar(menuBar); - - JMenu mnOptions = new JMenu("Options"); - menuBar.add(mnOptions); - - chckbxmntmRunInBackground = new JCheckBoxMenuItem("Run in background on exit"); - mnOptions.add(chckbxmntmRunInBackground); - chckbxmntmRunInBackground.addActionListener(this); - - chckbxmntmDelayStartup = new JCheckBoxMenuItem("Delay Startup"); - mnOptions.add(chckbxmntmDelayStartup); - chckbxmntmDelayStartup.addActionListener(this); - - chckbxmntmDownloadJars = new JCheckBoxMenuItem("Download jars"); - mnOptions.add(chckbxmntmDownloadJars); - chckbxmntmDownloadJars.addActionListener(this); - - JMenu mnHelp = new JMenu("Help"); - menuBar.add(mnHelp); - - mntmErrors = new JMenuItem("Errors"); - mnHelp.add(mntmErrors); - mntmErrors.addActionListener(this); - - mntmSetup = new JMenuItem("Setup"); - mnHelp.add(mntmSetup); - mntmSetup.addActionListener(this); - - mntmManualUpdate = new JMenuItem("Manual update"); - mnHelp.add(mntmManualUpdate); - mntmManualUpdate.addActionListener(this); - - JMenu mnInfo = new JMenu("Info"); - menuBar.add(mnInfo); - - JMenu mnOptionsInfo = new JMenu("Options"); - mnInfo.add(mnOptionsInfo); - - mntmRunInBackground = new JMenuItem("Run in background on exit"); - mnOptionsInfo.add(mntmRunInBackground); - mntmRunInBackground.addActionListener(this); - - mntmDelayStartup = new JMenuItem("Delay Startup"); - mnOptionsInfo.add(mntmDelayStartup); - mntmDelayStartup.addActionListener(this); - - mntmDownloadJars = new JMenuItem("Download jars"); - mnOptionsInfo.add(mntmDownloadJars); - mntmDownloadJars.addActionListener(this); - - JMenu mnAbout = new JMenu("About"); - mnInfo.add(mnAbout); - - mntmAbout = new JMenuItem("About"); - mnAbout.add(mntmAbout); - mntmAbout.addActionListener(this); - - mntmStory = new JMenuItem("Story"); - mnAbout.add(mntmStory); - mntmStory.addActionListener(this); - - tabbedPane = new JTabbedPane(JTabbedPane.TOP); - frame.getContentPane().add(tabbedPane); - - JPanel panelBasic = new JPanel(); - tabbedPane.addTab("Control panel", null, panelBasic, null); - SpringLayout sl_panel = new SpringLayout(); - panelBasic.setLayout(sl_panel); - - JLabel lblBasicControls = new JLabel("Basic controls"); - sl_panel.putConstraint(SpringLayout.NORTH, lblBasicControls, 10, SpringLayout.NORTH, panelBasic); - panelBasic.add(lblBasicControls); - - btnStartServer = new JButton("Start servers"); - sl_panel.putConstraint(SpringLayout.WEST, lblBasicControls, 0, SpringLayout.WEST, btnStartServer); - sl_panel.putConstraint(SpringLayout.NORTH, btnStartServer, 6, SpringLayout.SOUTH, lblBasicControls); - sl_panel.putConstraint(SpringLayout.WEST, btnStartServer, 10, SpringLayout.WEST, panelBasic); - panelBasic.add(btnStartServer); - btnStartServer.addActionListener(this); - - btnStopServer = new JButton("Stop servers"); - sl_panel.putConstraint(SpringLayout.NORTH, btnStopServer, 0, SpringLayout.NORTH, btnStartServer); - sl_panel.putConstraint(SpringLayout.WEST, btnStopServer, 6, SpringLayout.EAST, btnStartServer); - panelBasic.add(btnStopServer); - btnStopServer.addActionListener(this); - - JLabel lblProfile = new JLabel("Profile"); - sl_panel.putConstraint(SpringLayout.NORTH, lblProfile, 6, SpringLayout.SOUTH, btnStartServer); - sl_panel.putConstraint(SpringLayout.WEST, lblProfile, 10, SpringLayout.WEST, panelBasic); - panelBasic.add(lblProfile); - - addProfile = new JButton("+"); - sl_panel.putConstraint(SpringLayout.NORTH, addProfile, 6, SpringLayout.SOUTH, lblProfile); - sl_panel.putConstraint(SpringLayout.WEST, addProfile, 10, SpringLayout.WEST, panelBasic); - panelBasic.add(addProfile); - addProfile.addActionListener(this); - - delProfile = new JButton("-"); - sl_panel.putConstraint(SpringLayout.NORTH, delProfile, 0, SpringLayout.NORTH, addProfile); - sl_panel.putConstraint(SpringLayout.WEST, delProfile, 6, SpringLayout.EAST, addProfile); - panelBasic.add(delProfile); - delProfile.addActionListener(this); - - profiles = new JComboBox<>(); - sl_panel.putConstraint(SpringLayout.NORTH, profiles, 0, SpringLayout.NORTH, addProfile); - sl_panel.putConstraint(SpringLayout.WEST, profiles, 6, SpringLayout.EAST, delProfile); - sl_panel.putConstraint(SpringLayout.EAST, profiles, 124, SpringLayout.EAST, delProfile); - panelBasic.add(profiles); - profiles.addActionListener(this); - - sl_panel.putConstraint(SpringLayout.NORTH, lblStatuslabel, 6, SpringLayout.SOUTH, addProfile); - sl_panel.putConstraint(SpringLayout.SOUTH, lblStatuslabel, -10, SpringLayout.SOUTH, panelBasic); - sl_panel.putConstraint(SpringLayout.WEST, lblStatuslabel, 10, SpringLayout.WEST, panelBasic); - sl_panel.putConstraint(SpringLayout.EAST, lblStatuslabel, -10, SpringLayout.EAST, panelBasic); - panelBasic.add(lblStatuslabel); - - addServer = new JButton("Add server"); - sl_panel.putConstraint(SpringLayout.NORTH, addServer, 0, SpringLayout.NORTH, btnStartServer); - sl_panel.putConstraint(SpringLayout.WEST, addServer, 6, SpringLayout.EAST, btnStopServer); - panelBasic.add(addServer); - addServer.addActionListener(this); - - backup = new JButton("Backup"); - sl_panel.putConstraint(SpringLayout.NORTH, backup, 0, SpringLayout.NORTH, btnStartServer); - sl_panel.putConstraint(SpringLayout.WEST, backup, 6, SpringLayout.EAST, addServer); - panelBasic.add(backup); - backup.addActionListener(this); - - JPanel controlServers = new JPanel(); - tabbedPane.addTab("Control servers", null, controlServers, null); - SpringLayout sl_panel_1 = new SpringLayout(); - controlServers.setLayout(sl_panel_1); - - targetServer = new JComboBox<>(); - sl_panel_1.putConstraint(SpringLayout.NORTH, targetServer, 10, SpringLayout.NORTH, controlServers); - controlServers.add(targetServer); - targetServer.addActionListener(this); - - targetPlayer = new JComboBox<>(); - sl_panel_1.putConstraint(SpringLayout.NORTH, targetPlayer, 6, SpringLayout.SOUTH, targetServer); - targetPlayer.setEditable(true); - controlServers.add(targetPlayer); - - btnKick = new JButton("Kick"); - sl_panel_1.putConstraint(SpringLayout.NORTH, btnKick, 10, SpringLayout.NORTH, controlServers); - sl_panel_1.putConstraint(SpringLayout.WEST, btnKick, 6, SpringLayout.EAST, targetServer); - sl_panel_1.putConstraint(SpringLayout.EAST, btnKick, 104, SpringLayout.WEST, btnKick); - sl_panel_1.putConstraint(SpringLayout.SOUTH, targetServer, 0, SpringLayout.SOUTH, btnKick); - controlServers.add(btnKick); - btnKick.addActionListener(this); - - btnBan = new JButton("Ban"); - sl_panel_1.putConstraint(SpringLayout.NORTH, btnBan, 6, SpringLayout.SOUTH, btnKick); - sl_panel_1.putConstraint(SpringLayout.WEST, btnBan, 6, SpringLayout.EAST, targetPlayer); - sl_panel_1.putConstraint(SpringLayout.EAST, btnBan, 104, SpringLayout.WEST, btnBan); - sl_panel_1.putConstraint(SpringLayout.SOUTH, targetPlayer, 0, SpringLayout.SOUTH, btnBan); - controlServers.add(btnBan); - btnBan.addActionListener(this); - - btnOp = new JButton("OP"); - sl_panel_1.putConstraint(SpringLayout.NORTH, btnOp, 10, SpringLayout.NORTH, controlServers); - sl_panel_1.putConstraint(SpringLayout.WEST, btnOp, 6, SpringLayout.EAST, btnKick); - sl_panel_1.putConstraint(SpringLayout.EAST, btnOp, -10, SpringLayout.EAST, controlServers); - controlServers.add(btnOp); - btnOp.addActionListener(this); - - btnDeop = new JButton("DEOP"); - sl_panel_1.putConstraint(SpringLayout.WEST, btnDeop, 6, SpringLayout.EAST, btnBan); - sl_panel_1.putConstraint(SpringLayout.NORTH, btnDeop, 5, SpringLayout.SOUTH, btnOp); - sl_panel_1.putConstraint(SpringLayout.EAST, btnDeop, -10, SpringLayout.EAST, controlServers); - controlServers.add(btnDeop); - btnDeop.addActionListener(this); - - JLabel lblTargetServer = new JLabel("Target server"); - sl_panel_1.putConstraint(SpringLayout.WEST, targetServer, 6, SpringLayout.EAST, lblTargetServer); - sl_panel_1.putConstraint(SpringLayout.EAST, targetServer, 121, SpringLayout.EAST, lblTargetServer); - sl_panel_1.putConstraint(SpringLayout.NORTH, lblTargetServer, 10, SpringLayout.NORTH, controlServers); - sl_panel_1.putConstraint(SpringLayout.SOUTH, lblTargetServer, 0, SpringLayout.SOUTH, targetServer); - sl_panel_1.putConstraint(SpringLayout.WEST, lblTargetServer, 10, SpringLayout.WEST, controlServers); - controlServers.add(lblTargetServer); - - JLabel lblTargetPlayer = new JLabel("Target player"); - sl_panel_1.putConstraint(SpringLayout.WEST, targetPlayer, 7, SpringLayout.EAST, lblTargetPlayer); - sl_panel_1.putConstraint(SpringLayout.EAST, targetPlayer, 122, SpringLayout.EAST, lblTargetPlayer); - sl_panel_1.putConstraint(SpringLayout.NORTH, lblTargetPlayer, 6, SpringLayout.SOUTH, lblTargetServer); - sl_panel_1.putConstraint(SpringLayout.SOUTH, lblTargetPlayer, 0, SpringLayout.SOUTH, targetPlayer); - sl_panel_1.putConstraint(SpringLayout.WEST, lblTargetPlayer, 0, SpringLayout.WEST, lblTargetServer); - controlServers.add(lblTargetPlayer); - - btnCustomCommand = new JButton("Custom command"); - sl_panel_1.putConstraint(SpringLayout.WEST, btnCustomCommand, 250, SpringLayout.WEST, controlServers); - sl_panel_1.putConstraint(SpringLayout.EAST, btnCustomCommand, 0, SpringLayout.EAST, btnOp); - controlServers.add(btnCustomCommand); - btnCustomCommand.addActionListener(this); - frame.getRootPane().setDefaultButton(btnCustomCommand); - - customCommand = new JTextField(); - sl_panel_1.putConstraint(SpringLayout.WEST, customCommand, 10, SpringLayout.WEST, controlServers); - sl_panel_1.putConstraint(SpringLayout.EAST, customCommand, -6, SpringLayout.WEST, btnCustomCommand); - sl_panel_1.putConstraint(SpringLayout.NORTH, btnCustomCommand, 0, SpringLayout.NORTH, customCommand); - sl_panel_1.putConstraint(SpringLayout.SOUTH, customCommand, 0, SpringLayout.SOUTH, btnCustomCommand); - controlServers.add(customCommand); - customCommand.setColumns(10); - - btnSaveserver = new JButton("Save server"); - sl_panel_1.putConstraint(SpringLayout.NORTH, customCommand, 6, SpringLayout.SOUTH, btnSaveserver); - sl_panel_1.putConstraint(SpringLayout.NORTH, btnSaveserver, 6, SpringLayout.SOUTH, btnBan); - sl_panel_1.putConstraint(SpringLayout.WEST, btnSaveserver, 0, SpringLayout.WEST, btnKick); - sl_panel_1.putConstraint(SpringLayout.EAST, btnSaveserver, 104, SpringLayout.WEST, btnKick); - sl_panel_1.putConstraint(SpringLayout.EAST, btnSaveserver, 104, SpringLayout.WEST, btnKick); - controlServers.add(btnSaveserver); - btnSaveserver.addActionListener(this); - - btnReload = new JButton("Reload"); - sl_panel_1.putConstraint(SpringLayout.NORTH, btnReload, 6, SpringLayout.SOUTH, btnDeop); - sl_panel_1.putConstraint(SpringLayout.WEST, btnReload, 0, SpringLayout.WEST, btnDeop); - sl_panel_1.putConstraint(SpringLayout.EAST, btnReload, 0, SpringLayout.EAST, btnOp); - controlServers.add(btnReload); - btnReload.addActionListener(this); - - btnServerConsoles = new JButton("View server consoles"); - sl_panel_1.putConstraint(SpringLayout.NORTH, btnServerConsoles, 0, SpringLayout.NORTH, btnSaveserver); - sl_panel_1.putConstraint(SpringLayout.WEST, btnServerConsoles, 0, SpringLayout.WEST, lblTargetServer); - sl_panel_1.putConstraint(SpringLayout.EAST, btnServerConsoles, 0, SpringLayout.EAST, targetServer); - controlServers.add(btnServerConsoles); - btnServerConsoles.addActionListener(this); - - JPanel panel_2 = new JPanel(); - tabbedPane.addTab("Servers", null, panel_2, null); - SpringLayout sl_panel_2 = new SpringLayout(); - panel_2.setLayout(sl_panel_2); - - JTabbedPane tabbedPane_1 = new JTabbedPane(JTabbedPane.TOP); - sl_panel_2.putConstraint(SpringLayout.NORTH, tabbedPane_1, 0, SpringLayout.NORTH, panel_2); - sl_panel_2.putConstraint(SpringLayout.WEST, tabbedPane_1, 0, SpringLayout.WEST, panel_2); - sl_panel_2.putConstraint(SpringLayout.SOUTH, tabbedPane_1, 0, SpringLayout.SOUTH, panel_2); - sl_panel_2.putConstraint(SpringLayout.EAST, tabbedPane_1, 0, SpringLayout.EAST, panel_2); - panel_2.add(tabbedPane_1); - - this.serversPane = tabbedPane_1; - tabbedPane_1.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); - - frame.validate(); - frame.pack(); - frame.setVisible(true); - tray(); - updateRunning(false); - } - - /** - * Prepares the system tray if available. - */ - private void tray() { - if (SystemTray.isSupported()) { - tray = SystemTray.getSystemTray(); - Image trayImage = Toolkit.getDefaultToolkit().getImage("files/GUIIcon.png"); - PopupMenu popup = new PopupMenu(); - trayIcon = new TrayIcon(trayImage, "Minecraft Server Launcher", popup); - trayIcon.setImageAutoSize(true); - ActionListener exitListener= e -> { - stop(); - try { - Profile.getCurrent().save(); - } catch (FileNotFoundException e1) { - e1.printStackTrace(); - } - System.exit(0); - }; - - MenuItem restoreItem = new MenuItem("Restore"); - popup.add(restoreItem); - restoreItem.addActionListener(e -> { - frame.setExtendedState(NORMAL); - tray.remove(trayIcon); - frame.setVisible(true); - }); - MenuItem exitItem = new MenuItem("Exit"); - exitItem.addActionListener(exitListener); - popup.add(exitItem); - frame.addWindowStateListener(e -> { - if (e.getNewState() == NORMAL) { - tray.remove(trayIcon); - frame.setVisible(true); - } - }); - - frame.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - if (Profile.getCurrent().getRunInBackground() && SystemTray.isSupported()) { - try { - tray.add(trayIcon); - frame.setVisible(false); - } catch (AWTException e1) { - e1.printStackTrace(); - } - } else { - stop(); - try { - Profile.getCurrent().save(); - } catch (FileNotFoundException e1) { - e1.printStackTrace(); - } - System.exit(0); - } - } - }); - - trayIcon.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - if(e.getClickCount() >= 1 && e.getButton() == MouseEvent.BUTTON1){ - frame.setExtendedState(NORMAL); - tray.remove(trayIcon); - frame.setVisible(true); - } - } - }); - } else { - frame.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - try { - Profile.getCurrent().save(); - } catch (FileNotFoundException e1) { - e1.printStackTrace(); - } - stop(); - System.exit(0); - } - }); - } - } - - /** - * Hides the gui to the tray, - */ - public void hide() { - frame.setVisible(false); - try { - tray.add(trayIcon); - } catch (AWTException e) { - e.printStackTrace(); - } - } - - @Override - public void actionPerformed(ActionEvent e) { - String selectedServerValue = null, selectedPlayerValue = null; - Object selectedServer = targetServer.getSelectedItem(); - if (selectedServer != null) { - selectedServerValue = selectedServer.toString(); - } - Object selectedPlayer = targetPlayer.getSelectedItem(); - if (selectedPlayer != null) { - selectedPlayerValue = selectedPlayer.toString(); - } - if (e.getSource() == chckbxmntmRunInBackground) { - background(); - } else if (e.getSource() == chckbxmntmDelayStartup) { - delay(); - } else if (e.getSource() == chckbxmntmDownloadJars) { - downloadJars(); - } else if (e.getSource() == mntmErrors) { - Shared.goToURL("https://archive.knarcraft.net/Scripts/BungeeMinecraftServerLauncherInfo/"); - } else if (e.getSource() == mntmSetup) { - Profile.showMessage("Setup", setupText); - } else if (e.getSource() == mntmManualUpdate) { - Shared.goToURL("https://git.knarcraft.net/KnarCraft/Minecraft-Server-Launcher/releases"); - } else if (e.getSource() == mntmRunInBackground) { - Profile.showMessage("Run in background", runInBackgroundText); - } else if (e.getSource() == mntmDelayStartup) { - Profile.showMessage("Delay startup", delayStartupText); - } else if (e.getSource() == mntmDownloadJars) { - Profile.showMessage("Download jars", downloadJarsText); - } else if (e.getSource() == mntmAbout) { - Profile.showMessage("About", aboutText); - } else if (e.getSource() == mntmStory) { - Shared.goToURL("https://archive.knarcraft.net/Scripts/BungeeMinecraftServerLauncherStory/"); - } else if (e.getSource() == btnStartServer) { - try { - Profile.getCurrent().save(); - } catch (FileNotFoundException e1) { - e1.printStackTrace(); - } - Executors.newSingleThreadExecutor().execute(Server::startServers); - } else if (e.getSource() == btnStopServer) { - stop(); - } else if (e.getSource() == addServer) { - String serverName = JOptionPane.showInputDialog("Name of server: "); - Profile.getCurrent().addCollection(serverName); - this.update(); - Profile.getCurrent().updateConsoles(); - } else if (e.getSource() == backup) { - backup(); - } else if (e.getSource() == addProfile) { - Profile.addProfile(JOptionPane.showInputDialog("Profile name: ")); - updateProfiles(); - } else if (e.getSource() == delProfile) { - Object selected = profiles.getSelectedItem(); - if (selected != null) { - Profile.removeProfile(selected.toString()); - updateProfiles(); - } - } else if (e.getSource() == profiles) { - try { - changeProfile(); - } catch (FileNotFoundException e1) { - e1.printStackTrace(); - } - } else if (e.getSource() == btnKick) { - if (selectedServerValue != null && selectedPlayerValue != null) { - Profile.getCurrent().sendCommand(selectedServerValue, "kick " + selectedPlayerValue); - } - } else if (e.getSource() == btnBan) { - if (selectedServerValue != null && selectedPlayerValue != null) { - Profile.getCurrent().sendCommand(selectedServerValue, "ban " + selectedPlayerValue); - } - } else if (e.getSource() == btnOp) { - if (selectedServerValue != null && selectedPlayerValue != null) { - Profile.getCurrent().sendCommand(selectedServerValue, "op " + selectedPlayerValue); - } - } else if (e.getSource() == btnDeop) { - if (selectedServerValue != null && selectedPlayerValue != null) { - Profile.getCurrent().sendCommand(selectedServerValue, "deop " + selectedPlayerValue); - } - } else if (e.getSource() == btnCustomCommand) { - if (selectedServerValue != null) { - Profile.getCurrent().sendCommand(selectedServerValue, customCommand.getText()); - customCommand.setText(""); - } - } else if (e.getSource() == btnSaveserver) { - if (selectedServerValue != null) { - Profile.getCurrent().sendCommand(selectedServerValue, "save-all"); - } - } else if (e.getSource() == btnReload) { - if (selectedServerValue != null) { - Profile.getCurrent().sendCommand(selectedServerValue, "reload"); - } - } else if (e.getSource() == btnServerConsoles) { - ServerConsoles.setAsVisible(); - } else if (e.getSource() == targetServer) { - updatePlayers(); - } - } - - /** - * Updates the GUI components to block a user from doing illegal actions. - * - * @param running Are the servers currently running? - */ - public void updateRunning(boolean running) { - boolean stopped = !running; //Most gui is only enabled when the server is stopped rather than running. - profiles.setEnabled(stopped); - addProfile.setEnabled(stopped); - delProfile.setEnabled(stopped); - btnStartServer.setEnabled(stopped); - addServer.setEnabled(stopped); - tabbedPane.setEnabledAt(2, stopped); - btnStopServer.setEnabled(running); - } - - /** - * Saves the previous profile and loads data from the new profile. - */ - private void changeProfile() throws FileNotFoundException { - Profile.getCurrent().save(); - Object current = this.profiles.getSelectedItem(); - if (current != null) { - Profile.setCurrent(current.toString()); - } - this.update(); - Profile.getCurrent().updateConsoles(); - } - - /** - * Stops all servers - */ - private void stop() { - try { - setStatus("Servers are stopping..."); - Server.stop(); - } catch (IOException e1) { - Profile.showError("Could not stop server."); - e1.printStackTrace(); - } - } - - /** - * Asks the user for a delay if checked, and sets the value to the current profile. - */ - private void delay() { - Object selected = profiles.getSelectedItem(); - if (selected != null) { - Profile profile = Profile.getProfile(selected.toString()); - if (chckbxmntmDelayStartup.isSelected()) { - Objects.requireNonNull(profile).setDelayStartup( - Integer.parseInt(JOptionPane.showInputDialog("Seconds to delay: ")) - ); - } else { - Objects.requireNonNull(profile).setDelayStartup(0); - } - } else { - Profile.showError("No profile selected"); - } - } - - /** - * Saves the runInBackground setting to the current profile. - */ - private void background() { - Object selected = profiles.getSelectedItem(); - if (selected != null) { - Profile profile = Profile.getProfile(selected.toString()); - Objects.requireNonNull(profile).setRunInBackground(chckbxmntmRunInBackground.isSelected()); - } else { - Profile.showError("No profile selected"); - } - } - - /** - * Saves the downloadJars setting to the current profile. - */ - private void downloadJars() { - Object selected = profiles.getSelectedItem(); - if (selected != null) { - Profile profile = Profile.getProfile(selected.toString()); - Objects.requireNonNull(profile).setDownloadAllAvailableJARFiles(chckbxmntmDownloadJars.isSelected()); - } else { - Profile.showError("No profile selected"); - } - } - - /** - * Copies all server directories to a folder specified by the user. - */ - private void backup() { - JFileChooser chooser = new JFileChooser(); - chooser.setCurrentDirectory(new java.io.File(".")); - chooser.setDialogTitle("Backup folder"); - chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - chooser.setAcceptAllFileFilterUsed(false); - if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { - File path = chooser.getSelectedFile(); - for (Collection collection : Profile.getCurrent().getCollections()) { - if (!collection.getServer().getPath().equals("") && collection.getServer().isEnabled()) { - String name = collection.getServer().getName(); - File srcFolder = new File(collection.getServer().getPath()); - File destFolder = new File(path, name); - if (!destFolder.exists()) { - if (destFolder.mkdirs()) { - try { - Shared.copyFolder(this, srcFolder, destFolder); - } catch (IOException e) { - e.printStackTrace(); - return; - } - } else { - return; - } - } - } - } - } - this.setStatus("Backup finished"); - } - - /** - * Updates the list of players currently online on the selected server, - */ - private void updatePlayers() { - String selectedServerValue; - Object selectedServer = targetServer.getSelectedItem(); - if (selectedServer != null) { - targetPlayer.removeAllItems(); - selectedServerValue = selectedServer.toString(); - if (selectedServerValue.equals("All")) { - for (String player : this.globalPlayers) { - targetPlayer.addItem(player); - } - } else { - for (String player : Profile.getCurrent().getCollection(selectedServerValue).getServer().getPlayers()) { - targetPlayer.addItem(player); - } - } - } - } - - /** - * Loads popup messages from a text file. - */ - private void loadMessages() throws FileNotFoundException { - Scanner file = getResourceAsScanner("menumsg.csv"); - while (file.hasNextLine()) { - String nextLine = file.nextLine(); - String[] line = nextLine.split("="); - String content = line[1].replaceAll("_BREAK_", System.getProperty("line.separator")); - switch (line[0]) { - case "setup": - setupText = content; - break; - case "runinbk": - runInBackgroundText = content; - break; - case "delaystartup": - delayStartupText = content; - break; - case "downloadjars": - downloadJarsText = content; - break; - case "about": - aboutText = content; - } - } - } } diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/MessageHandler.java b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/MessageHandler.java new file mode 100644 index 0000000..e083b30 --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/MessageHandler.java @@ -0,0 +1,61 @@ +package net.knarcraft.minecraftserverlauncher.userinterface; + +import javax.swing.*; + +public abstract class MessageHandler implements GUI { + + private final boolean silent; + + /*** + * Initializes a new message handler + * + * @param silent

Whether to print to cli instead of showing a GUI element

+ */ + public MessageHandler(boolean silent) { + this.silent = silent; + } + + @Override + public void showError(String title, String message) { + if (silent) { + System.out.println(message); + } else { + showJOptionPane(title, message, JOptionPane.ERROR_MESSAGE); + } + } + + @Override + public void showError(String message) { + showError("Error", message); + } + + @Override + public void showMessage(String title, String message) { + if (silent) { + System.out.println(message); + } else { + showJOptionPane(title, message, JOptionPane.INFORMATION_MESSAGE); + } + } + + @Override + public void showMessage(String message) { + showMessage("Info", message); + } + + /** + * Shows a JOptionPane + * + * @param title

The title of the pane

+ * @param message

The message of the pane

+ * @param paneType

The type of the pane

+ */ + private void showJOptionPane(String title, String message, int paneType) { + JOptionPane.showMessageDialog( + null, + message, + title, + paneType + ); + } +} diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherGUI.java b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherGUI.java new file mode 100644 index 0000000..5d304ec --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherGUI.java @@ -0,0 +1,811 @@ +package net.knarcraft.minecraftserverlauncher.userinterface; + +import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions; +import net.knarcraft.minecraftserverlauncher.profile.Collection; +import net.knarcraft.minecraftserverlauncher.Main; +import net.knarcraft.minecraftserverlauncher.server.Server; +import net.knarcraft.minecraftserverlauncher.profile.Profile; + +import javax.imageio.ImageIO; +import javax.naming.ConfigurationException; +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.util.ArrayList; +import java.util.Objects; +import java.util.Scanner; +import java.util.concurrent.Executors; + +import static java.awt.Frame.NORMAL; +import static javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE; +import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.getResourceAsScanner; +import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.getResourceAsStream; + +/** + * Generates a ServerLauncherGUI. + * + * @author Kristian Knarvik + * @version 1.0.0 + * @since 1.0.0 + */ +public class ServerLauncherGUI extends MessageHandler implements ActionListener, GUI { + + private JFrame frame; + private JTabbedPane tabbedPane; + private JTabbedPane serversPane; + //Menu + private JCheckBoxMenuItem chckbxmntmRunInBackground, chckbxmntmDelayStartup, chckbxmntmDownloadJars; //Options + private JMenuItem mntmErrors, mntmSetup, mntmManualUpdate; //Help + private JMenuItem mntmRunInBackground, mntmDelayStartup, mntmDownloadJars; //Info/options + private JMenuItem mntmAbout, mntmStory; //Info/about + //Basic controls + private JButton btnStartServer, btnStopServer, addServer, backup, addProfile, delProfile; + private JComboBox profiles; + private final JLabel lblStatuslabel = new JLabel("Servers are stopped"); + //Server controls + private JComboBox targetServer; + private JComboBox targetPlayer; + private JButton btnKick, btnBan, btnOp, btnDeop, btnCustomCommand, btnSaveserver, btnReload, btnServerConsoles; + private JTextField customCommand; + //Text + private String setupText; + private String runInBackgroundText; + private String delayStartupText; + private String downloadJarsText; + private String aboutText; + + private final ArrayList globalPlayers; + private SystemTray tray; + private TrayIcon trayIcon; + + /** + * Creates the application window + */ + public ServerLauncherGUI() throws IOException { + super(false); + initialize(440, 170); + loadMessages(); + this.globalPlayers = new ArrayList<>(); + } + + /** + * Creates the application window with a preferred width and height + * @param width

The preferred width

+ * @param height

The preferred height

+ */ + public ServerLauncherGUI(int width, int height) throws IOException { + super(false); + initialize(width, height); + loadMessages(); + this.globalPlayers = new ArrayList<>(); + } + + /** + * Gets the pane used for server configurations + * + * @return A JTabbedPane + */ + public JTabbedPane getPane() { + return this.serversPane; + } + + /** + * Sets the text of the status label. + * + * @param text The new text + */ + public void setStatus(String text) { + this.lblStatuslabel.setText(text); + try (PrintWriter file = new PrintWriter(new FileWriter(Main.getApplicationWorkDirectory() + File.separator + "latestrun.log", true))) { + file.println(text); + } catch (IOException e ) { + e.printStackTrace(); + } + } + + /** + * Adds a player to the global playerlist, and updates the players combo. + * + * @param name The name of the player to add + */ + public void addPlayer(String name) { + this.globalPlayers.add(name); + this.updatePlayers(); + } + + /** + * Removes a player from the global list of players. + * + * @param name The name of the player to remove. + */ + public void removePlayer(String name) { + globalPlayers.removeIf(playerName -> playerName.equals(name)); + this.updatePlayers(); + } + + /** + * Updates the profiles combo. + */ + public void updateProfiles() { + this.profiles.removeAllItems(); + for (Profile profile : Profile.getProfiles()) { + this.profiles.addItem(profile.getName()); + } + } + + /** + * Gets the size of the main JFrame + * + * @return The Dimension of the frame + */ + public Dimension getSize() { + return frame.getContentPane().getSize(); + } + + /** + * Updates ServerLauncherGUI according to current profile settings. + */ + public void update() { + serversPane.removeAll(); + for (Collection collection : Profile.getCurrent().getCollections()) { + serversPane.addTab(collection.getName(), collection.getServerTab().getPanel()); + } + chckbxmntmRunInBackground.setState(Profile.getCurrent().getRunInBackground()); + chckbxmntmDelayStartup.setState(Profile.getCurrent().getDelayStartup() > 0); + chckbxmntmDownloadJars.setState(Profile.getCurrent().getDownloadAllAvailableJARFiles()); + this.targetServer.removeAllItems(); + this.targetServer.addItem("All"); + for (Collection collection : Profile.getCurrent().getCollections()) { + this.targetServer.addItem(collection.getName()); + } + } + + /** + * Creates the ServerLauncherGUI, + */ + private void initialize(int width, int height) throws IOException { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (ClassNotFoundException | + UnsupportedLookAndFeelException | + InstantiationException | + IllegalAccessException e + ) { + e.printStackTrace(); + } + + frame = new JFrame("Minecraft server launcher"); + frame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + frame.getContentPane().setPreferredSize(new Dimension(width, height)); + + ImageIcon img = new ImageIcon(ImageIO.read(getResourceAsStream("GUIIcon.png"))); + + frame.setIconImage(img.getImage()); + + JMenuBar menuBar = new JMenuBar(); + frame.setJMenuBar(menuBar); + + JMenu mnOptions = new JMenu("Options"); + menuBar.add(mnOptions); + + chckbxmntmRunInBackground = new JCheckBoxMenuItem("Run in background on exit"); + mnOptions.add(chckbxmntmRunInBackground); + chckbxmntmRunInBackground.addActionListener(this); + + chckbxmntmDelayStartup = new JCheckBoxMenuItem("Delay Startup"); + mnOptions.add(chckbxmntmDelayStartup); + chckbxmntmDelayStartup.addActionListener(this); + + chckbxmntmDownloadJars = new JCheckBoxMenuItem("Download jars"); + mnOptions.add(chckbxmntmDownloadJars); + chckbxmntmDownloadJars.addActionListener(this); + + JMenu mnHelp = new JMenu("Help"); + menuBar.add(mnHelp); + + mntmErrors = new JMenuItem("Errors"); + mnHelp.add(mntmErrors); + mntmErrors.addActionListener(this); + + mntmSetup = new JMenuItem("Setup"); + mnHelp.add(mntmSetup); + mntmSetup.addActionListener(this); + + mntmManualUpdate = new JMenuItem("Manual update"); + mnHelp.add(mntmManualUpdate); + mntmManualUpdate.addActionListener(this); + + JMenu mnInfo = new JMenu("Info"); + menuBar.add(mnInfo); + + JMenu mnOptionsInfo = new JMenu("Options"); + mnInfo.add(mnOptionsInfo); + + mntmRunInBackground = new JMenuItem("Run in background on exit"); + mnOptionsInfo.add(mntmRunInBackground); + mntmRunInBackground.addActionListener(this); + + mntmDelayStartup = new JMenuItem("Delay Startup"); + mnOptionsInfo.add(mntmDelayStartup); + mntmDelayStartup.addActionListener(this); + + mntmDownloadJars = new JMenuItem("Download jars"); + mnOptionsInfo.add(mntmDownloadJars); + mntmDownloadJars.addActionListener(this); + + JMenu mnAbout = new JMenu("About"); + mnInfo.add(mnAbout); + + mntmAbout = new JMenuItem("About"); + mnAbout.add(mntmAbout); + mntmAbout.addActionListener(this); + + mntmStory = new JMenuItem("Story"); + mnAbout.add(mntmStory); + mntmStory.addActionListener(this); + + tabbedPane = new JTabbedPane(JTabbedPane.TOP); + frame.getContentPane().add(tabbedPane); + + JPanel panelBasic = new JPanel(); + tabbedPane.addTab("Control panel", null, panelBasic, null); + SpringLayout sl_panel = new SpringLayout(); + panelBasic.setLayout(sl_panel); + + JLabel lblBasicControls = new JLabel("Basic controls"); + sl_panel.putConstraint(SpringLayout.NORTH, lblBasicControls, 10, SpringLayout.NORTH, panelBasic); + panelBasic.add(lblBasicControls); + + btnStartServer = new JButton("Start servers"); + sl_panel.putConstraint(SpringLayout.WEST, lblBasicControls, 0, SpringLayout.WEST, btnStartServer); + sl_panel.putConstraint(SpringLayout.NORTH, btnStartServer, 6, SpringLayout.SOUTH, lblBasicControls); + sl_panel.putConstraint(SpringLayout.WEST, btnStartServer, 10, SpringLayout.WEST, panelBasic); + panelBasic.add(btnStartServer); + btnStartServer.addActionListener(this); + + btnStopServer = new JButton("Stop servers"); + sl_panel.putConstraint(SpringLayout.NORTH, btnStopServer, 0, SpringLayout.NORTH, btnStartServer); + sl_panel.putConstraint(SpringLayout.WEST, btnStopServer, 6, SpringLayout.EAST, btnStartServer); + panelBasic.add(btnStopServer); + btnStopServer.addActionListener(this); + + JLabel lblProfile = new JLabel("Profile"); + sl_panel.putConstraint(SpringLayout.NORTH, lblProfile, 6, SpringLayout.SOUTH, btnStartServer); + sl_panel.putConstraint(SpringLayout.WEST, lblProfile, 10, SpringLayout.WEST, panelBasic); + panelBasic.add(lblProfile); + + addProfile = new JButton("+"); + sl_panel.putConstraint(SpringLayout.NORTH, addProfile, 6, SpringLayout.SOUTH, lblProfile); + sl_panel.putConstraint(SpringLayout.WEST, addProfile, 10, SpringLayout.WEST, panelBasic); + panelBasic.add(addProfile); + addProfile.addActionListener(this); + + delProfile = new JButton("-"); + sl_panel.putConstraint(SpringLayout.NORTH, delProfile, 0, SpringLayout.NORTH, addProfile); + sl_panel.putConstraint(SpringLayout.WEST, delProfile, 6, SpringLayout.EAST, addProfile); + panelBasic.add(delProfile); + delProfile.addActionListener(this); + + profiles = new JComboBox<>(); + sl_panel.putConstraint(SpringLayout.NORTH, profiles, 0, SpringLayout.NORTH, addProfile); + sl_panel.putConstraint(SpringLayout.WEST, profiles, 6, SpringLayout.EAST, delProfile); + sl_panel.putConstraint(SpringLayout.EAST, profiles, 124, SpringLayout.EAST, delProfile); + panelBasic.add(profiles); + profiles.addActionListener(this); + + sl_panel.putConstraint(SpringLayout.NORTH, lblStatuslabel, 6, SpringLayout.SOUTH, addProfile); + sl_panel.putConstraint(SpringLayout.SOUTH, lblStatuslabel, -10, SpringLayout.SOUTH, panelBasic); + sl_panel.putConstraint(SpringLayout.WEST, lblStatuslabel, 10, SpringLayout.WEST, panelBasic); + sl_panel.putConstraint(SpringLayout.EAST, lblStatuslabel, -10, SpringLayout.EAST, panelBasic); + panelBasic.add(lblStatuslabel); + + addServer = new JButton("Add server"); + sl_panel.putConstraint(SpringLayout.NORTH, addServer, 0, SpringLayout.NORTH, btnStartServer); + sl_panel.putConstraint(SpringLayout.WEST, addServer, 6, SpringLayout.EAST, btnStopServer); + panelBasic.add(addServer); + addServer.addActionListener(this); + + backup = new JButton("Backup"); + sl_panel.putConstraint(SpringLayout.NORTH, backup, 0, SpringLayout.NORTH, btnStartServer); + sl_panel.putConstraint(SpringLayout.WEST, backup, 6, SpringLayout.EAST, addServer); + panelBasic.add(backup); + backup.addActionListener(this); + + JPanel controlServers = new JPanel(); + tabbedPane.addTab("Control servers", null, controlServers, null); + SpringLayout sl_panel_1 = new SpringLayout(); + controlServers.setLayout(sl_panel_1); + + targetServer = new JComboBox<>(); + sl_panel_1.putConstraint(SpringLayout.NORTH, targetServer, 10, SpringLayout.NORTH, controlServers); + controlServers.add(targetServer); + targetServer.addActionListener(this); + + targetPlayer = new JComboBox<>(); + sl_panel_1.putConstraint(SpringLayout.NORTH, targetPlayer, 6, SpringLayout.SOUTH, targetServer); + targetPlayer.setEditable(true); + controlServers.add(targetPlayer); + + btnKick = new JButton("Kick"); + sl_panel_1.putConstraint(SpringLayout.NORTH, btnKick, 10, SpringLayout.NORTH, controlServers); + sl_panel_1.putConstraint(SpringLayout.WEST, btnKick, 6, SpringLayout.EAST, targetServer); + sl_panel_1.putConstraint(SpringLayout.EAST, btnKick, 104, SpringLayout.WEST, btnKick); + sl_panel_1.putConstraint(SpringLayout.SOUTH, targetServer, 0, SpringLayout.SOUTH, btnKick); + controlServers.add(btnKick); + btnKick.addActionListener(this); + + btnBan = new JButton("Ban"); + sl_panel_1.putConstraint(SpringLayout.NORTH, btnBan, 6, SpringLayout.SOUTH, btnKick); + sl_panel_1.putConstraint(SpringLayout.WEST, btnBan, 6, SpringLayout.EAST, targetPlayer); + sl_panel_1.putConstraint(SpringLayout.EAST, btnBan, 104, SpringLayout.WEST, btnBan); + sl_panel_1.putConstraint(SpringLayout.SOUTH, targetPlayer, 0, SpringLayout.SOUTH, btnBan); + controlServers.add(btnBan); + btnBan.addActionListener(this); + + btnOp = new JButton("OP"); + sl_panel_1.putConstraint(SpringLayout.NORTH, btnOp, 10, SpringLayout.NORTH, controlServers); + sl_panel_1.putConstraint(SpringLayout.WEST, btnOp, 6, SpringLayout.EAST, btnKick); + sl_panel_1.putConstraint(SpringLayout.EAST, btnOp, -10, SpringLayout.EAST, controlServers); + controlServers.add(btnOp); + btnOp.addActionListener(this); + + btnDeop = new JButton("DEOP"); + sl_panel_1.putConstraint(SpringLayout.WEST, btnDeop, 6, SpringLayout.EAST, btnBan); + sl_panel_1.putConstraint(SpringLayout.NORTH, btnDeop, 5, SpringLayout.SOUTH, btnOp); + sl_panel_1.putConstraint(SpringLayout.EAST, btnDeop, -10, SpringLayout.EAST, controlServers); + controlServers.add(btnDeop); + btnDeop.addActionListener(this); + + JLabel lblTargetServer = new JLabel("Target server"); + sl_panel_1.putConstraint(SpringLayout.WEST, targetServer, 6, SpringLayout.EAST, lblTargetServer); + sl_panel_1.putConstraint(SpringLayout.EAST, targetServer, 121, SpringLayout.EAST, lblTargetServer); + sl_panel_1.putConstraint(SpringLayout.NORTH, lblTargetServer, 10, SpringLayout.NORTH, controlServers); + sl_panel_1.putConstraint(SpringLayout.SOUTH, lblTargetServer, 0, SpringLayout.SOUTH, targetServer); + sl_panel_1.putConstraint(SpringLayout.WEST, lblTargetServer, 10, SpringLayout.WEST, controlServers); + controlServers.add(lblTargetServer); + + JLabel lblTargetPlayer = new JLabel("Target player"); + sl_panel_1.putConstraint(SpringLayout.WEST, targetPlayer, 7, SpringLayout.EAST, lblTargetPlayer); + sl_panel_1.putConstraint(SpringLayout.EAST, targetPlayer, 122, SpringLayout.EAST, lblTargetPlayer); + sl_panel_1.putConstraint(SpringLayout.NORTH, lblTargetPlayer, 6, SpringLayout.SOUTH, lblTargetServer); + sl_panel_1.putConstraint(SpringLayout.SOUTH, lblTargetPlayer, 0, SpringLayout.SOUTH, targetPlayer); + sl_panel_1.putConstraint(SpringLayout.WEST, lblTargetPlayer, 0, SpringLayout.WEST, lblTargetServer); + controlServers.add(lblTargetPlayer); + + btnCustomCommand = new JButton("Custom command"); + sl_panel_1.putConstraint(SpringLayout.WEST, btnCustomCommand, 250, SpringLayout.WEST, controlServers); + sl_panel_1.putConstraint(SpringLayout.EAST, btnCustomCommand, 0, SpringLayout.EAST, btnOp); + controlServers.add(btnCustomCommand); + btnCustomCommand.addActionListener(this); + frame.getRootPane().setDefaultButton(btnCustomCommand); + + customCommand = new JTextField(); + sl_panel_1.putConstraint(SpringLayout.WEST, customCommand, 10, SpringLayout.WEST, controlServers); + sl_panel_1.putConstraint(SpringLayout.EAST, customCommand, -6, SpringLayout.WEST, btnCustomCommand); + sl_panel_1.putConstraint(SpringLayout.NORTH, btnCustomCommand, 0, SpringLayout.NORTH, customCommand); + sl_panel_1.putConstraint(SpringLayout.SOUTH, customCommand, 0, SpringLayout.SOUTH, btnCustomCommand); + controlServers.add(customCommand); + customCommand.setColumns(10); + + btnSaveserver = new JButton("Save server"); + sl_panel_1.putConstraint(SpringLayout.NORTH, customCommand, 6, SpringLayout.SOUTH, btnSaveserver); + sl_panel_1.putConstraint(SpringLayout.NORTH, btnSaveserver, 6, SpringLayout.SOUTH, btnBan); + sl_panel_1.putConstraint(SpringLayout.WEST, btnSaveserver, 0, SpringLayout.WEST, btnKick); + sl_panel_1.putConstraint(SpringLayout.EAST, btnSaveserver, 104, SpringLayout.WEST, btnKick); + sl_panel_1.putConstraint(SpringLayout.EAST, btnSaveserver, 104, SpringLayout.WEST, btnKick); + controlServers.add(btnSaveserver); + btnSaveserver.addActionListener(this); + + btnReload = new JButton("Reload"); + sl_panel_1.putConstraint(SpringLayout.NORTH, btnReload, 6, SpringLayout.SOUTH, btnDeop); + sl_panel_1.putConstraint(SpringLayout.WEST, btnReload, 0, SpringLayout.WEST, btnDeop); + sl_panel_1.putConstraint(SpringLayout.EAST, btnReload, 0, SpringLayout.EAST, btnOp); + controlServers.add(btnReload); + btnReload.addActionListener(this); + + btnServerConsoles = new JButton("View server consoles"); + sl_panel_1.putConstraint(SpringLayout.NORTH, btnServerConsoles, 0, SpringLayout.NORTH, btnSaveserver); + sl_panel_1.putConstraint(SpringLayout.WEST, btnServerConsoles, 0, SpringLayout.WEST, lblTargetServer); + sl_panel_1.putConstraint(SpringLayout.EAST, btnServerConsoles, 0, SpringLayout.EAST, targetServer); + controlServers.add(btnServerConsoles); + btnServerConsoles.addActionListener(this); + + JPanel panel_2 = new JPanel(); + tabbedPane.addTab("Servers", null, panel_2, null); + SpringLayout sl_panel_2 = new SpringLayout(); + panel_2.setLayout(sl_panel_2); + + JTabbedPane tabbedPane_1 = new JTabbedPane(JTabbedPane.TOP); + sl_panel_2.putConstraint(SpringLayout.NORTH, tabbedPane_1, 0, SpringLayout.NORTH, panel_2); + sl_panel_2.putConstraint(SpringLayout.WEST, tabbedPane_1, 0, SpringLayout.WEST, panel_2); + sl_panel_2.putConstraint(SpringLayout.SOUTH, tabbedPane_1, 0, SpringLayout.SOUTH, panel_2); + sl_panel_2.putConstraint(SpringLayout.EAST, tabbedPane_1, 0, SpringLayout.EAST, panel_2); + panel_2.add(tabbedPane_1); + + this.serversPane = tabbedPane_1; + tabbedPane_1.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); + + frame.validate(); + frame.pack(); + frame.setVisible(true); + tray(); + updateRunning(false); + } + + /** + * Prepares the system tray if available. + */ + private void tray() { + if (SystemTray.isSupported()) { + tray = SystemTray.getSystemTray(); + Image trayImage = Toolkit.getDefaultToolkit().getImage("files/GUIIcon.png"); + PopupMenu popup = new PopupMenu(); + trayIcon = new TrayIcon(trayImage, "Minecraft Server Launcher", popup); + trayIcon.setImageAutoSize(true); + ActionListener exitListener= e -> { + stop(); + try { + Profile.getCurrent().save(); + } catch (FileNotFoundException e1) { + e1.printStackTrace(); + } + System.exit(0); + }; + + MenuItem restoreItem = new MenuItem("Restore"); + popup.add(restoreItem); + restoreItem.addActionListener(e -> { + frame.setExtendedState(NORMAL); + tray.remove(trayIcon); + frame.setVisible(true); + }); + MenuItem exitItem = new MenuItem("Exit"); + exitItem.addActionListener(exitListener); + popup.add(exitItem); + frame.addWindowStateListener(e -> { + if (e.getNewState() == NORMAL) { + tray.remove(trayIcon); + frame.setVisible(true); + } + }); + + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + if (Profile.getCurrent().getRunInBackground() && SystemTray.isSupported()) { + try { + tray.add(trayIcon); + frame.setVisible(false); + } catch (AWTException e1) { + e1.printStackTrace(); + } + } else { + stop(); + try { + Profile.getCurrent().save(); + } catch (FileNotFoundException e1) { + e1.printStackTrace(); + } + System.exit(0); + } + } + }); + + trayIcon.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + if(e.getClickCount() >= 1 && e.getButton() == MouseEvent.BUTTON1){ + frame.setExtendedState(NORMAL); + tray.remove(trayIcon); + frame.setVisible(true); + } + } + }); + } else { + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + try { + Profile.getCurrent().save(); + } catch (FileNotFoundException e1) { + e1.printStackTrace(); + } + stop(); + System.exit(0); + } + }); + } + } + + /** + * Hides the gui to the tray, + */ + public void hide() { + frame.setVisible(false); + try { + tray.add(trayIcon); + } catch (AWTException e) { + e.printStackTrace(); + } + } + + @Override + public void actionPerformed(ActionEvent e) { + String selectedServerValue = null, selectedPlayerValue = null; + Object selectedServer = targetServer.getSelectedItem(); + if (selectedServer != null) { + selectedServerValue = selectedServer.toString(); + } + Object selectedPlayer = targetPlayer.getSelectedItem(); + if (selectedPlayer != null) { + selectedPlayerValue = selectedPlayer.toString(); + } + if (e.getSource() == chckbxmntmRunInBackground) { + background(); + } else if (e.getSource() == chckbxmntmDelayStartup) { + delay(); + } else if (e.getSource() == chckbxmntmDownloadJars) { + downloadJars(); + } else if (e.getSource() == mntmErrors) { + CommonFunctions.goToURL("https://archive.knarcraft.net/Scripts/BungeeMinecraftServerLauncherInfo/"); + } else if (e.getSource() == mntmSetup) { + showMessage("Setup", setupText); + } else if (e.getSource() == mntmManualUpdate) { + CommonFunctions.goToURL("https://git.knarcraft.net/KnarCraft/Minecraft-Server-Launcher/releases"); + } else if (e.getSource() == mntmRunInBackground) { + showMessage("Run in background", runInBackgroundText); + } else if (e.getSource() == mntmDelayStartup) { + showMessage("Delay startup", delayStartupText); + } else if (e.getSource() == mntmDownloadJars) { + showMessage("Download jars", downloadJarsText); + } else if (e.getSource() == mntmAbout) { + showMessage("About", aboutText); + } else if (e.getSource() == mntmStory) { + CommonFunctions.goToURL("https://archive.knarcraft.net/Scripts/BungeeMinecraftServerLauncherStory/"); + } else if (e.getSource() == btnStartServer) { + try { + Profile.getCurrent().save(); + } catch (FileNotFoundException e1) { + e1.printStackTrace(); + } + Executors.newSingleThreadExecutor().execute(Server::startServers); + } else if (e.getSource() == btnStopServer) { + stop(); + } else if (e.getSource() == addServer) { + String serverName = JOptionPane.showInputDialog("Name of server: "); + try { + Profile.getCurrent().addCollection(serverName); + } catch (ConfigurationException e1) { + e1.printStackTrace(); + } + this.update(); + Profile.getCurrent().updateConsoles(); + } else if (e.getSource() == backup) { + backup(); + } else if (e.getSource() == addProfile) { + Profile.addProfile(JOptionPane.showInputDialog("Profile name: ")); + updateProfiles(); + } else if (e.getSource() == delProfile) { + Object selected = profiles.getSelectedItem(); + if (selected != null) { + Profile.removeProfile(selected.toString()); + updateProfiles(); + } + } else if (e.getSource() == profiles) { + try { + changeProfile(); + } catch (FileNotFoundException e1) { + e1.printStackTrace(); + } + } else if (e.getSource() == btnKick) { + if (selectedServerValue != null && selectedPlayerValue != null) { + Profile.getCurrent().sendCommand(selectedServerValue, "kick " + selectedPlayerValue); + } + } else if (e.getSource() == btnBan) { + if (selectedServerValue != null && selectedPlayerValue != null) { + Profile.getCurrent().sendCommand(selectedServerValue, "ban " + selectedPlayerValue); + } + } else if (e.getSource() == btnOp) { + if (selectedServerValue != null && selectedPlayerValue != null) { + Profile.getCurrent().sendCommand(selectedServerValue, "op " + selectedPlayerValue); + } + } else if (e.getSource() == btnDeop) { + if (selectedServerValue != null && selectedPlayerValue != null) { + Profile.getCurrent().sendCommand(selectedServerValue, "deop " + selectedPlayerValue); + } + } else if (e.getSource() == btnCustomCommand) { + if (selectedServerValue != null) { + Profile.getCurrent().sendCommand(selectedServerValue, customCommand.getText()); + customCommand.setText(""); + } + } else if (e.getSource() == btnSaveserver) { + if (selectedServerValue != null) { + Profile.getCurrent().sendCommand(selectedServerValue, "save-all"); + } + } else if (e.getSource() == btnReload) { + if (selectedServerValue != null) { + Profile.getCurrent().sendCommand(selectedServerValue, "reload"); + } + } else if (e.getSource() == btnServerConsoles) { + ServerConsoles.setAsVisible(); + } else if (e.getSource() == targetServer) { + updatePlayers(); + } + } + + /** + * Updates the ServerLauncherGUI components to block a user from doing illegal actions. + * + * @param running Are the servers currently running? + */ + public void updateRunning(boolean running) { + boolean stopped = !running; //Most gui is only enabled when the server is stopped rather than running. + profiles.setEnabled(stopped); + addProfile.setEnabled(stopped); + delProfile.setEnabled(stopped); + btnStartServer.setEnabled(stopped); + addServer.setEnabled(stopped); + tabbedPane.setEnabledAt(2, stopped); + btnStopServer.setEnabled(running); + } + + /** + * Saves the previous profile and loads data from the new profile. + */ + private void changeProfile() throws FileNotFoundException { + Profile.getCurrent().save(); + Object current = this.profiles.getSelectedItem(); + if (current != null) { + Profile.setCurrent(current.toString()); + } + this.update(); + Profile.getCurrent().updateConsoles(); + } + + /** + * Stops all servers + */ + private void stop() { + try { + setStatus("Servers are stopping..."); + Server.stop(); + } catch (IOException e1) { + showError("Could not stop server."); + e1.printStackTrace(); + } + } + + /** + * Asks the user for a delay if checked, and sets the value to the current profile. + */ + private void delay() { + Object selected = profiles.getSelectedItem(); + if (selected != null) { + Profile profile = Profile.getProfile(selected.toString()); + if (chckbxmntmDelayStartup.isSelected()) { + Objects.requireNonNull(profile).setDelayStartup( + Integer.parseInt(JOptionPane.showInputDialog("Seconds to delay: ")) + ); + } else { + Objects.requireNonNull(profile).setDelayStartup(0); + } + } else { + showError("No profile selected"); + } + } + + /** + * Saves the runInBackground setting to the current profile. + */ + private void background() { + Object selected = profiles.getSelectedItem(); + if (selected != null) { + Profile profile = Profile.getProfile(selected.toString()); + Objects.requireNonNull(profile).setRunInBackground(chckbxmntmRunInBackground.isSelected()); + } else { + showError("No profile selected"); + } + } + + /** + * Saves the downloadJars setting to the current profile. + */ + private void downloadJars() { + Object selected = profiles.getSelectedItem(); + if (selected != null) { + Profile profile = Profile.getProfile(selected.toString()); + Objects.requireNonNull(profile).setDownloadAllAvailableJARFiles(chckbxmntmDownloadJars.isSelected()); + } else { + showError("No profile selected"); + } + } + + /** + * Copies all server directories to a folder specified by the user. + */ + private void backup() { + JFileChooser chooser = new JFileChooser(); + chooser.setCurrentDirectory(new java.io.File(".")); + chooser.setDialogTitle("Backup folder"); + chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + chooser.setAcceptAllFileFilterUsed(false); + if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { + File path = chooser.getSelectedFile(); + for (Collection collection : Profile.getCurrent().getCollections()) { + if (!collection.getServer().getPath().equals("") && collection.getServer().isEnabled()) { + String name = collection.getServer().getName(); + File srcFolder = new File(collection.getServer().getPath()); + File destFolder = new File(path, name); + if (!destFolder.exists()) { + if (destFolder.mkdirs()) { + try { + CommonFunctions.copyFolder(this, srcFolder, destFolder); + } catch (IOException e) { + e.printStackTrace(); + return; + } + } else { + return; + } + } + } + } + } + this.setStatus("Backup finished"); + } + + /** + * Updates the list of players currently online on the selected server, + */ + private void updatePlayers() { + String selectedServerValue; + Object selectedServer = targetServer.getSelectedItem(); + if (selectedServer != null) { + targetPlayer.removeAllItems(); + selectedServerValue = selectedServer.toString(); + if (selectedServerValue.equals("All")) { + for (String player : this.globalPlayers) { + targetPlayer.addItem(player); + } + } else { + for (String player : Profile.getCurrent().getCollection(selectedServerValue).getServer().getPlayers()) { + targetPlayer.addItem(player); + } + } + } + } + + /** + * Loads popup messages from a text file. + */ + private void loadMessages() throws FileNotFoundException { + Scanner file = getResourceAsScanner("menumsg.csv"); + while (file.hasNextLine()) { + String nextLine = file.nextLine(); + String[] line = nextLine.split("="); + String content = line[1].replaceAll("_BREAK_", System.getProperty("line.separator")); + switch (line[0]) { + case "setup": + setupText = content; + break; + case "runinbk": + runInBackgroundText = content; + break; + case "delaystartup": + delayStartupText = content; + break; + case "downloadjars": + downloadJarsText = content; + break; + case "about": + aboutText = content; + } + } + } + + @Override + public void printMessageToGUI(String message) { + setStatus(message); + } +} diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerTab.java b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerTab.java index 72df3c9..ed0ec9c 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerTab.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerTab.java @@ -2,8 +2,10 @@ package net.knarcraft.minecraftserverlauncher.userinterface; import net.knarcraft.minecraftserverlauncher.profile.Profile; import net.knarcraft.minecraftserverlauncher.server.Server; -import net.knarcraft.minecraftserverlauncher.server.ServerType; +import net.knarcraft.minecraftserverlauncher.server.servertypes.ServerType; +import net.knarcraft.minecraftserverlauncher.server.ServerTypeHandler; +import javax.naming.ConfigurationException; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -33,7 +35,7 @@ public class ServerTab implements ActionListener { * @param serverVersion The version of the server * @param maxRam The max usable ram for the server */ - public void setData(String path, boolean enabled, String typeName, String serverVersion, String maxRam) { + public void setData(String path, boolean enabled, String typeName, String serverVersion, String maxRam) throws ConfigurationException { this.directory.setText(path); this.chckbxEnabled.setSelected(enabled); this.serverTypes.setSelectedItem(typeName); @@ -42,7 +44,7 @@ public class ServerTab implements ActionListener { this.maxRam.setSelectedItem(maxRam); } - public ServerTab(String name) { + public ServerTab(String name) throws ConfigurationException { this.name = name; panel = new JPanel(); Profile.getGUI().getPane().addTab(name, null, panel, null); @@ -59,7 +61,7 @@ public class ServerTab implements ActionListener { sl_panel_3.putConstraint(SpringLayout.SOUTH, lblServerVersion, 26, SpringLayout.SOUTH, lblServerType); panel.add(lblServerVersion); - serverTypes = new JComboBox<>(ServerType.getTypeNames()); + serverTypes = new JComboBox<>(ServerTypeHandler.getTypeNames()); sl_panel_3.putConstraint(SpringLayout.NORTH, serverTypes, 10, SpringLayout.NORTH, panel); sl_panel_3.putConstraint(SpringLayout.WEST, serverTypes, 5, SpringLayout.EAST, lblServerVersion); sl_panel_3.putConstraint(SpringLayout.EAST, serverTypes, 154, SpringLayout.WEST, serverTypes); @@ -68,7 +70,7 @@ public class ServerTab implements ActionListener { panel.add(serverTypes); serverTypes.addActionListener(this); - serverVersions = new JComboBox<>(ServerType.getServerTypes().get(0).getVersions()); + serverVersions = new JComboBox<>(ServerTypeHandler.getServerTypes().get(0).getVersions()); sl_panel_3.putConstraint(SpringLayout.NORTH, serverVersions, 6, SpringLayout.SOUTH, serverTypes); sl_panel_3.putConstraint(SpringLayout.EAST, serverVersions, 0, SpringLayout.EAST, serverTypes); sl_panel_3.putConstraint(SpringLayout.WEST, serverVersions, 6, SpringLayout.EAST, lblServerVersion); @@ -183,7 +185,11 @@ public class ServerTab implements ActionListener { } else if (e.getSource() == btnBrowse) { browse(); } else if (e.getSource() == serverTypes) { - serverTypes(); + try { + serverTypes(); + } catch (ConfigurationException e1) { + e1.printStackTrace(); + } } } @@ -214,7 +220,7 @@ public class ServerTab implements ActionListener { /** * Updates the versions combo according to the value of the server type combo. */ - private void serverTypes() { + private void serverTypes() throws ConfigurationException { serverVersions.removeAllItems(); String selectedserverTypes = null; Object selectedType = serverTypes.getSelectedItem(); @@ -227,7 +233,7 @@ public class ServerTab implements ActionListener { } else { serverVersions.setEditable(false); ServerType current = null; - for (ServerType servertype : ServerType.getServerTypes()) { + for (ServerType servertype : ServerTypeHandler.getServerTypes()) { if (servertype.getName().equals(selectedserverTypes)) { current = servertype; } diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/Shared.java b/src/main/java/net/knarcraft/minecraftserverlauncher/utility/CommonFunctions.java similarity index 50% rename from src/main/java/net/knarcraft/minecraftserverlauncher/Shared.java rename to src/main/java/net/knarcraft/minecraftserverlauncher/utility/CommonFunctions.java index 8bc0d91..c5ccb5a 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/Shared.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/utility/CommonFunctions.java @@ -1,6 +1,6 @@ -package net.knarcraft.minecraftserverlauncher; +package net.knarcraft.minecraftserverlauncher.utility; -import net.knarcraft.minecraftserverlauncher.userinterface.GUI; +import net.knarcraft.minecraftserverlauncher.userinterface.ServerLauncherGUI; import java.io.*; import java.net.URI; @@ -18,11 +18,13 @@ import java.util.Scanner; * @version 1.0.0 * @since 1.0.0 */ -public class Shared { +public class CommonFunctions { + /** * Gets a resource as an InputStream - * @param resourceName

The name of the resource you want to read.

- * @return

An input stream which can be used to access the resource.

+ * + * @param resourceName

The name of the resource you want to read

+ * @return

An input stream which can be used to access the resource

*/ public static InputStream getResourceAsStream(String resourceName) { ClassLoader classloader = Thread.currentThread().getContextClassLoader(); @@ -31,9 +33,10 @@ public class Shared { /** * Gets a resource as a Scanner - * @param resourceName

The name of the resource you want to read.

- * @return

A scanner which can be used to read contents of the resource.

- * @throws FileNotFoundException

If the resource is not found.

+ * + * @param resourceName

The name of the resource you want to read

+ * @return

A scanner which can be used to read contents of the resource

+ * @throws FileNotFoundException

If the resource is not found

*/ public static Scanner getResourceAsScanner(String resourceName) throws FileNotFoundException { InputStream is = getResourceAsStream(resourceName); @@ -44,12 +47,12 @@ public class Shared { } /** - * Finds a substring between two substrings in a string. + * Finds a substring between two substrings in a string * - * @param string The string containing the substrings - * @param start The substring before the wanted substring - * @param end The substring after the wanted substring - * @return The wanted substring. + * @param string

The string containing the substrings

+ * @param start

The substring before the wanted substring

+ * @param end

The substring after the wanted substring

+ * @return

The wanted substring

*/ public static String stringBetween(String string, String start, String end) { int startPos = string.indexOf(start) + start.length(); @@ -60,11 +63,12 @@ public class Shared { } /** - * Reads a file from a website. - * This is used to find the newest version of jars and the software. + * Reads a file from a website * - * @param path The full url of the file to read - * @return True if successful. False otherwise + *

This is used to find the newest version of jars and the software.

+ * + * @param path

The full url of the file to read

+ * @return

True if successful. False otherwise

*/ public static String readFile(String path) throws IOException { URL url = new URL(path); @@ -72,11 +76,11 @@ public class Shared { } /** - * Downloads a file from a website. + * Downloads a file from a website and replaces the target file * - * @param path The full url of the file to download. - * @param outfile The file to save to - * @return True if successful. False otherwise + * @param path

The full url of the file to download

+ * @param outfile

The file to save to

+ * @return

True if successful. False otherwise

*/ public static boolean downloadFile(String path, Path outfile) { try { @@ -90,46 +94,57 @@ public class Shared { } /** - * Recursivly copies a folder to another location + * Recursively copies a folder to another location * - * @param src

The folder to copy

- * @param dest

Target destination

+ * @param source

The folder to copy

+ * @param destination

Target destination

* @throws IOException

If we can't start a file stream

*/ - public static void copyFolder(GUI gui, File src, File dest) throws IOException { - if (!src.isDirectory()) { - InputStream in = new FileInputStream(src); - OutputStream out = new FileOutputStream(dest); - byte[] buffer = new byte[1024]; - int length; - while ((length = in.read(buffer)) > 0){ - out.write(buffer, 0, length); - } - in.close(); - out.close(); - gui.setStatus("Copied file " + src); + public static void copyFolder(ServerLauncherGUI serverLauncherGui, File source, File destination) throws IOException { + if (!source.isDirectory()) { + copyFile(serverLauncherGui, source, destination); } else { - if(!dest.exists()){ - if (dest.mkdir()) { - gui.setStatus("Copied directory " + src); - } else { - return; - } + serverLauncherGui.setStatus("Copying directory " + source); + if (!destination.exists() && !destination.mkdir()) { + return; } - String[] files = src.list(); + String[] files = source.list(); if (files != null) { for (String file : files) { - File srcFile = new File(src, file); - File destFile = new File(dest, file); - copyFolder(gui, srcFile, destFile); + File srcFile = new File(source, file); + File destinationFile = new File(destination, file); + copyFolder(serverLauncherGui, srcFile, destinationFile); } } + serverLauncherGui.setStatus("Copied directory " + source); } } + /** + * Copies a file from one location to another + * + * @param serverLauncherGui

The serverLauncherGui to use for alerting the user

+ * @param source

The file to copy

+ * @param destination

The location of the copied file

+ * @throws IOException

If reading or writing fails

+ */ + private static void copyFile(ServerLauncherGUI serverLauncherGui, File source, File destination) throws IOException { + serverLauncherGui.setStatus("Copying file " + source + "..."); + InputStream in = new FileInputStream(source); + OutputStream out = new FileOutputStream(destination); + byte[] buffer = new byte[1024]; + int length; + while ((length = in.read(buffer)) > 0) { + out.write(buffer, 0, length); + } + in.close(); + out.close(); + serverLauncherGui.setStatus("Copied file " + source); + } + /** * Opens an url in the user's default application. - * @param url

URL to open

+ * @param url

The URL to open

*/ public static void goToURL(String url) { java.awt.Desktop desktop = java.awt.Desktop.getDesktop(); diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/utility/JarDownloader.java b/src/main/java/net/knarcraft/minecraftserverlauncher/utility/JarDownloader.java new file mode 100644 index 0000000..e125ed0 --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/utility/JarDownloader.java @@ -0,0 +1,68 @@ +package net.knarcraft.minecraftserverlauncher.utility; + +import net.knarcraft.minecraftserverlauncher.server.servertypes.ServerType; +import net.knarcraft.minecraftserverlauncher.server.ServerTypeHandler; +import net.knarcraft.minecraftserverlauncher.userinterface.GUI; + +import javax.naming.ConfigurationException; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +/** + * This class handles all downloading of .jar files + */ +public class JarDownloader { + + private final String jarDirectory; + private GUI gui; + + /** + * Initializes a jar downloader + * + * @param gui

The GUI to use for displaying messages

+ * @param jarDirectory

The directory to download jar files to

+ */ + public JarDownloader(GUI gui, String jarDirectory) { + this.gui = gui; + this.jarDirectory = jarDirectory; + } + + /** + * Downloads all jars to the program directory. + * + * @throws IOException On version file failure or folder creation failure + */ + public void downloadJars() throws IOException { + if (!new File(jarDirectory).exists() && !new File(jarDirectory).mkdirs()) { + gui.showError("Could not create the Jars folder. Please run the program with admin permissions, or move it to " + + "a writable directory."); + throw new FileNotFoundException("Unable to create jars folder"); + } + try { + downloadAll(); + gui.printMessageToGUI("Finished downloading jars"); + } catch (FileNotFoundException | ConfigurationException e) { + throw new FileNotFoundException("One or more downloads failed: " + e.getMessage()); + } + } + + /** + * Downloads jar files for all possible server versions + * + * @throws IOException

If a jar fails to download

+ */ + private void downloadAll() throws IOException, ConfigurationException { + for (ServerType type : ServerTypeHandler.getServerTypes()) { + if (type.getName().equals("Custom")) { + continue; + } + for (String version : type.getVersions()) { + boolean success = type.downloadJar(jarDirectory, version); + if (!success) { + throw new FileNotFoundException("Unable to download the jar file for " + type.getName() + version); + } + } + } + } +} diff --git a/src/main/resources/servertypes.csv b/src/main/resources/servertypes.csv index 880afb9..be651e1 100644 --- a/src/main/resources/servertypes.csv +++ b/src/main/resources/servertypes.csv @@ -1,8 +1,9 @@ -Vanilla;Latest,1.16.1,1.15.2,1.14.4,1.13.2,1.12.2,1.11.2,1.10.2,1.9.4,1.8.9,1.7.10,1.6.4,1.5.2,1.4.7,1.3.2,1.2.5;https://launchermeta.mojang.com/mc/game/version_manifest.json;"release":";";https://s3.amazonaws.com/Minecraft.Download/versions/;/minecraft_server. -Snapshot;Latest;https://launchermeta.mojang.com/mc/game/version_manifest.json;"snapshot":";";https://s3.amazonaws.com/Minecraft.Download/versions/;/minecraft_server. SpongeVanilla;1.12.2,1.11.2,1.10.2,1.8.9;https://dl-api.spongepowered.org/v1/org.spongepowered/spongevanilla/downloads?type=stable&minecraft=;"version":";",;https://repo.spongepowered.org/maven/org/spongepowered/spongevanilla/;/spongevanilla- +Spigot;1.16.1,1.15.2,1.14.4,1.13.2,1.12.2,1.11.2,1.10.2,1.9.4,1.9.4,1.8.8,1.7.10,1.6.4,1.5.2,1.4.7;https://static.knarcraft.net/archive/downloads/minecraftserverjars/Spigot/;Spigot +MCPCplus;1.6.4,1.6.2,1.5.2,1.4.7;https://static.knarcraft.net/archive/downloads/minecraftserverjars/MCPC+/;mcpcplus +Craftbukkit;1.13.2,1.12.2,1.11.2,1.10.2,1.9.4,1.8.8,1.7.10-R0.1,1.6.4-R2.0,1.5.2-R1.0,1.4.6-R0.3,1.3.2-R3.0,1.2.5-R2.0,1.1-R6,1.0.1-R1;https://static.knarcraft.net/archive/downloads/minecraftserverjars/Bukkit/;craftbukkit- +Paper;1.16.1,1.15.2,1.14.4,1.13.2,1.12.2,1.11.2,1.10.2,1.9.4,1.8.8;https://static.knarcraft.net/archive/downloads/minecraftserverjars/Paper/;Paper- Bungee;Latest;https://ci.md-5.net/job/BungeeCord/lastSuccessfulBuild/artifact/bootstrap/target/;Artifacts of BungeeCord #; ;http://ci.md-5.net/job/BungeeCord/lastSuccessfulBuild/artifact/bootstrap/target/BungeeCord.jar; -Spigot;1.15.2,1.14.4,1.13.2,1.12.2,1.11.2,1.10.2,1.9.4,1.9.4,1.8.8,1.7.10,1.6.4,1.5.2,1.4.7;https://static.knarcraft.net/public/jars/ -MCPCplus;1.6.4,1.6.2,1.5.2,1.4.7;https://static.knarcraft.net/public/jars/ -Craftbukkit;1.13.2,1.12.2,1.11.2,1.10.2,1.9.4,1.8.8,1.7.10,1.6.4,1.5.2,1.4.6,1.3.2,1.2.5,1.1,1.0;https://static.knarcraft.net/public/jars/ +Snapshot;Latest;https://launchermeta.mojang.com/mc/game/version_manifest.json;"snapshot":";";https://s3.amazonaws.com/Minecraft.Download/versions/ +Vanilla;Latest,1.16.1,1.15.2,1.14.4,1.13.2,1.12.2,1.11.2,1.10.2,1.9.4,1.8.9,1.7.10,1.6.4,1.5.2,1.4.7,1.3.2,1.2.5;https://launchermeta.mojang.com/mc/game/version_manifest.json;"release":";";https://s3.amazonaws.com/Minecraft.Download/versions/ Custom;; \ No newline at end of file diff --git a/src/test/java/net/knarcraft/minecraftserverlauncher/DownloadTests.java b/src/test/java/net/knarcraft/minecraftserverlauncher/DownloadTests.java index 479a115..d84ca1f 100644 --- a/src/test/java/net/knarcraft/minecraftserverlauncher/DownloadTests.java +++ b/src/test/java/net/knarcraft/minecraftserverlauncher/DownloadTests.java @@ -1,15 +1,17 @@ package net.knarcraft.minecraftserverlauncher; -import net.knarcraft.minecraftserverlauncher.server.ServerType; +import net.knarcraft.minecraftserverlauncher.userinterface.FakeGUI; +import net.knarcraft.minecraftserverlauncher.utility.JarDownloader; import org.junit.Test; -import javax.naming.ConfigurationException; +import java.io.File; import java.io.IOException; public class DownloadTests { @Test - public void downloadJarsTest() throws ConfigurationException { - ServerType.loadServerTypes(); - //Profile.downloadJars(); + public void downloadJarsTest() throws IOException { + String targetDirectory = Main.getApplicationWorkDirectory() + File.separator + "files" + File.separator + "testjars" + File.separator; + JarDownloader downloader = new JarDownloader(new FakeGUI(), targetDirectory); + downloader.downloadJars(); } } diff --git a/src/test/java/net/knarcraft/minecraftserverlauncher/Tests.java b/src/test/java/net/knarcraft/minecraftserverlauncher/Tests.java index 2cf3ca2..61f95d5 100644 --- a/src/test/java/net/knarcraft/minecraftserverlauncher/Tests.java +++ b/src/test/java/net/knarcraft/minecraftserverlauncher/Tests.java @@ -1,20 +1,14 @@ package net.knarcraft.minecraftserverlauncher; import net.knarcraft.minecraftserverlauncher.profile.Profile; -import net.knarcraft.minecraftserverlauncher.server.ServerType; import org.junit.Test; -import javax.naming.ConfigurationException; import java.io.FileNotFoundException; -import static net.knarcraft.minecraftserverlauncher.Shared.stringBetween; +import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.stringBetween; import static org.junit.Assert.assertEquals; public class Tests { - @Test - public void loadServerVersions() throws ConfigurationException { //Make sure the server versions file has correct syntax - ServerType.loadServerTypes(); - } @Test public void saveProfile() throws FileNotFoundException { //Make sure we can write profiles to disk diff --git a/src/test/java/net/knarcraft/minecraftserverlauncher/userinterface/FakeGUI.java b/src/test/java/net/knarcraft/minecraftserverlauncher/userinterface/FakeGUI.java new file mode 100644 index 0000000..a65fa04 --- /dev/null +++ b/src/test/java/net/knarcraft/minecraftserverlauncher/userinterface/FakeGUI.java @@ -0,0 +1,16 @@ +package net.knarcraft.minecraftserverlauncher.userinterface; + +public class FakeGUI extends MessageHandler implements GUI { + + /*** + * Initializes a new fake gui + */ + public FakeGUI() { + super(true); + } + + @Override + public void printMessageToGUI(String message) { + System.out.println(message); + } +}