From a2d4d491bad23866078620e496cdcad574f2f885 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 7 Aug 2020 04:08:05 +0200 Subject: [PATCH] Fixes some bugs preventing servers from starting --- .../minecraftserverlauncher/Main.java | 5 +- .../server/Server.java | 195 ++++++++++++------ .../server/servertypes/Vanilla.java | 4 +- .../utility/CommonFunctions.java | 35 ++-- 4 files changed, 158 insertions(+), 81 deletions(-) diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java b/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java index f598bf4..fab5f68 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java @@ -83,7 +83,7 @@ public class Main { Server server = collection.getServer(); if (server.isEnabled() && server.getProcess() != null) { try { - String readText = server.read(); + String readText = server.readFromServer(); if (!readText.equals("")) { collection.getServerConsole().output(readText); updatePlayerList(readText, server); @@ -117,7 +117,8 @@ public class Main { private static boolean serversRunning() { int num = 0; for (Collection collection : Profile.getCurrent().getCollections()) { - if (collection.getServer().isStarted() || (collection.getServer().getProcess() != null && collection.getServer().getProcess().isAlive())) { + if (collection.getServer().isStarted() || + (collection.getServer().getProcess() != null && collection.getServer().getProcess().isAlive())) { num++; } } diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java index 0a5d638..f503693 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java @@ -48,6 +48,11 @@ public class Server { private final String bungeeVersion; private boolean started; + /** + * Initializes a new server with default values + * + * @param name

The name of the server

+ */ public Server(String name) { this.name = name; this.path = ""; @@ -65,6 +70,20 @@ public class Server { this.bungeeVersion = ""; } + /** + * Initializes a server with the given values + * + * @param name

The name of the server

+ * @param path

The file path of the folder containing the server files

+ * @param enabled

Whether the server is enabled to start the next time servers are started

+ * @param typeName

The name of the server type currently in use on the server

+ * @param serverVersion

The currently selected server version for the given server type

+ * @param maxRam

The maximum amount of ram the server is allowed to use

+ * @param vanillaVersion

The version of the "latest" downloaded vanilla version

+ * @param snapshotVersion

The version of the "latest" downloaded snapshot version

+ * @param spongeVanillaVersion

The version of the "latest" SpongeVanilla jar downloaded

+ * @param bungeeVersion

The version of the "latest" bungee jar downloaded

+ */ 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; @@ -80,18 +99,38 @@ public class Server { this.playerList = new ArrayList<>(); } + /** + * Gets the name of the server + * + * @return

The name of the server

+ */ public String getName() { return this.name; } + /** + * Whether the server has been started + * + * @return

True if the server has been started. False otherwise

+ */ public boolean isStarted() { return started; } + /** + * Gets the name of the server type used by this server + * + * @return

The name of the server type used by this server

+ */ public String getTypeName() { return this.type.getName(); } + /** + * Gets the version used given server type used + * + * @return

The server version given server type

+ */ public String getServerVersion() { return this.serverVersion; } @@ -255,76 +294,39 @@ public class Server { } /** - * Runs the Minecraft server. + * Runs a Minecraft server + * + * @return

True if nothing went wrong

*/ private boolean run() { - if (this.enabled) { - this.started = true; - if (!Profile.getCurrent().getDownloadAllAvailableJARFiles()) { - try { - Profile.getGUI().setStatus("Downloading jar..."); - this.downloadJar(); - Profile.getGUI().setStatus("File downloaded"); - } catch (IOException e) { - System.out.println(e.getMessage()); - Profile.getGUI().setStatus("Error: Jar file not found"); - e.printStackTrace(); - this.started = false; - return false; - } - } - try { - Profile.getGUI().setStatus("Delaying startup"); - TimeUnit.SECONDS.sleep(Profile.getCurrent().getDelayStartup()); - } catch (InterruptedException e) { - e.printStackTrace(); - this.started = false; - return false; - } - try { - ProcessBuilder builder; - String serverPath; - if (Profile.getCurrent().getDownloadAllAvailableJARFiles() && !type.getName().equals("Custom")) { - serverPath = jarDirectory + this.getType(); - } else { - serverPath = this.path + File.separator + this.getType(); - } - builder = new ProcessBuilder( - "java", - "-Xmx" + this.maxRam, - "-Xms512M", - "-Djline.terminal=jline.UnsupportedTerminal", - "-Dcom.mojang.eula.agree=true", - "-jar", - serverPath, - "nogui" - ); - builder.directory(new File(this.path)); - 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())); - Profile.getGUI().setStatus("Servers are running"); - this.started = true; - return true; - } catch (IOException e) { - Profile.getGUI().setStatus("Could not start server"); - this.started = false; - return false; - } - } else { + if (!this.enabled) { this.started = false; return true; } + this.started = true; + if (!initializeJarDownload() || !delayStartup()) { + return false; + } + + try { + startServerProcess(); + Profile.getGUI().setStatus("Servers are running"); + this.started = true; + return true; + } catch (IOException e) { + Profile.getGUI().setStatus("Could not start server"); + this.started = false; + return false; + } } /** - * Reads all available output from the server process. + * 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 { + public String readFromServer() throws IOException { String line; StringBuilder text = new StringBuilder(); while (reader.ready() && (line = reader.readLine()) != null) { @@ -334,10 +336,77 @@ 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. + * Starts the process running this server * - * @throws FileNotFoundException if the file was not found and could not be acquired. + * @throws IOException

If the process cannot be started

+ */ + private void startServerProcess() throws IOException { + ProcessBuilder builder; + String serverPath; + String serverFile; + if (type.getName().equals("Custom")) { + serverFile = serverVersion; + } else { + serverFile = this.type.getName() + serverVersion + ".jar"; + } + if (Profile.getCurrent().getDownloadAllAvailableJARFiles() && !type.getName().equals("Custom")) { + serverPath = jarDirectory + serverFile; + } else { + serverPath = this.path + File.separator + serverFile; + } + builder = new ProcessBuilder("java", "-Xmx" + this.maxRam, "-Xms512M", + "-Djline.terminal=jline.UnsupportedTerminal", "-Dcom.mojang.eula.agree=true", "-jar", serverPath, + "nogui"); + builder.directory(new File(this.path)); + 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())); + } + + /** + * Delays the server's startup for the given amount of time + * + * @return

True if the delay was successful

+ */ + private boolean delayStartup() { + try { + Profile.getGUI().setStatus("Delaying startup"); + TimeUnit.SECONDS.sleep(Profile.getCurrent().getDelayStartup()); + return true; + } catch (InterruptedException e) { + e.printStackTrace(); + this.started = false; + return false; + } + } + + /** + * Starts downloading the necessary .jar file + * + * @return

True if nothing went wrong

+ */ + private boolean initializeJarDownload() { + if (!Profile.getCurrent().getDownloadAllAvailableJARFiles()) { + try { + Profile.getGUI().setStatus("Downloading jar..."); + this.downloadJar(); + Profile.getGUI().setStatus("File downloaded"); + } catch (IOException e) { + System.out.println(e.getMessage()); + Profile.getGUI().setStatus("Error: Jar file not found"); + e.printStackTrace(); + this.started = false; + return false; + } + } + return true; + } + + /** + * Downloads necessary .jar file for the server. + * + * @throws FileNotFoundException

If the file was not found and could not be acquired

*/ private void downloadJar() throws IOException { String path = this.path + File.separator; diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Vanilla.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Vanilla.java index 67912d4..8668d66 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Vanilla.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Vanilla.java @@ -54,7 +54,7 @@ public class Vanilla extends AbstractServerType { * 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

+ * @throws IOException

If the remote resource cannot be readFromServer

*/ private String[] getLatestFile() throws IOException { String versionText = readFile(versionURL); @@ -70,7 +70,7 @@ public class Vanilla extends AbstractServerType { * * @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

+ * @throws IOException

If the remote resource cannot be readFromServer

*/ private String getVanillaDownloadURL(String versionURL) throws IOException { String versionText = readFile(versionURL); diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/utility/CommonFunctions.java b/src/main/java/net/knarcraft/minecraftserverlauncher/utility/CommonFunctions.java index c5ccb5a..6674e1c 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/utility/CommonFunctions.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/utility/CommonFunctions.java @@ -2,7 +2,13 @@ package net.knarcraft.minecraftserverlauncher.utility; import net.knarcraft.minecraftserverlauncher.userinterface.ServerLauncherGUI; -import java.io.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; @@ -14,16 +20,16 @@ import java.util.Scanner; /** * A holding class for methods shared between classes. * - * @author Kristian Knarvik - * @version 1.0.0 - * @since 1.0.0 + * @author Kristian Knarvik + * @version 1.0.0 + * @since 1.0.0 */ public class CommonFunctions { /** * Gets a resource as an InputStream * - * @param resourceName

The name of the resource you want to read

+ * @param resourceName

The name of the resource you want to readFromServer

* @return

An input stream which can be used to access the resource

*/ public static InputStream getResourceAsStream(String resourceName) { @@ -34,8 +40,8 @@ public class CommonFunctions { /** * 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

+ * @param resourceName

The name of the resource you want to readFromServer

+ * @return

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

* @throws FileNotFoundException

If the resource is not found

*/ public static Scanner getResourceAsScanner(String resourceName) throws FileNotFoundException { @@ -50,8 +56,8 @@ public class CommonFunctions { * 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

+ * @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) { @@ -67,7 +73,7 @@ public class CommonFunctions { * *

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

* - * @param path

The full url of the file to read

+ * @param path

The full url of the file to readFromServer

* @return

True if successful. False otherwise

*/ public static String readFile(String path) throws IOException { @@ -78,7 +84,7 @@ public class CommonFunctions { /** * Downloads a file from a website and replaces the target file * - * @param path

The full url of the file to download

+ * @param path

The full url of the file to download

* @param outfile

The file to save to

* @return

True if successful. False otherwise

*/ @@ -96,7 +102,7 @@ public class CommonFunctions { /** * Recursively copies a folder to another location * - * @param source

The folder to copy

+ * @param source

The folder to copy

* @param destination

Target destination

* @throws IOException

If we can't start a file stream

*/ @@ -124,8 +130,8 @@ public class CommonFunctions { * 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

+ * @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 { @@ -144,6 +150,7 @@ public class CommonFunctions { /** * Opens an url in the user's default application. + * * @param url

The URL to open

*/ public static void goToURL(String url) {