From 44d8d6ee6b9a885a22896a08c3dbc1c7828b2bc5 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 21 Aug 2021 13:43:27 +0200 Subject: [PATCH] Extracts a ServerHandler from the Server class to reduce complexity --- .../minecraftserverlauncher/Main.java | 4 +- .../profile/Profile.java | 5 +- .../profile/ServerLauncherController.java | 3 +- .../server/Server.java | 192 ++++++------------ .../server/ServerHandler.java | 140 +++++++++++++ .../userinterface/ServerLauncherGUI.java | 6 +- .../userinterface/ServerTab.java | 4 +- .../server/ServerTest.java | 2 +- 8 files changed, 212 insertions(+), 144 deletions(-) create mode 100644 src/main/java/net/knarcraft/minecraftserverlauncher/server/ServerHandler.java diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java b/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java index 64f2c8b..35d5731 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java @@ -2,7 +2,7 @@ package net.knarcraft.minecraftserverlauncher; import net.knarcraft.minecraftserverlauncher.profile.Collection; import net.knarcraft.minecraftserverlauncher.profile.ServerLauncherController; -import net.knarcraft.minecraftserverlauncher.server.Server; +import net.knarcraft.minecraftserverlauncher.server.ServerHandler; import net.knarcraft.minecraftserverlauncher.userinterface.ServerConsoles; import net.knarcraft.minecraftserverlauncher.userinterface.ServerLauncherGUI; import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions; @@ -88,7 +88,7 @@ public class Main { boolean runningNew = serversRunning(); if (serversAreRunning && !runningNew) { //Servers stopped running - Server.serversStopped(); + ServerHandler.serversStopped(); gui.updateGUIElementsWhenServersStartOrStop(false); gui.setStatus("Servers are stopped"); } else if (!serversAreRunning && runningNew) { diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Profile.java b/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Profile.java index f562faa..3884c48 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Profile.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Profile.java @@ -2,6 +2,7 @@ package net.knarcraft.minecraftserverlauncher.profile; import net.knarcraft.minecraftserverlauncher.Main; import net.knarcraft.minecraftserverlauncher.server.Server; +import net.knarcraft.minecraftserverlauncher.server.ServerHandler; import net.knarcraft.minecraftserverlauncher.userinterface.ServerConsoles; import net.knarcraft.minecraftserverlauncher.userinterface.ServerLauncherGUI; import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions; @@ -239,10 +240,10 @@ public class Profile { if (data[1].contains("!")) { String[] servers = data[1].split("!", -1); for (String server : servers) { - profile.collections.add(new Collection(Server.fromString(server))); + profile.collections.add(new Collection(ServerHandler.fromString(server))); } } else { - profile.collections.add(new Collection(Server.fromString(data[1]))); + profile.collections.add(new Collection(ServerHandler.fromString(data[1]))); } } else { profile = parseProfile(profileString.split(";", -1)); diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/profile/ServerLauncherController.java b/src/main/java/net/knarcraft/minecraftserverlauncher/profile/ServerLauncherController.java index 5237002..70f3ea9 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/profile/ServerLauncherController.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/profile/ServerLauncherController.java @@ -2,6 +2,7 @@ package net.knarcraft.minecraftserverlauncher.profile; import net.knarcraft.minecraftserverlauncher.Main; import net.knarcraft.minecraftserverlauncher.server.Server; +import net.knarcraft.minecraftserverlauncher.server.ServerHandler; import net.knarcraft.minecraftserverlauncher.server.ServerTypeHandler; import net.knarcraft.minecraftserverlauncher.userinterface.ServerLauncherGUI; import net.knarcraft.minecraftserverlauncher.userinterface.ServerTab; @@ -392,7 +393,7 @@ public class ServerLauncherController { }); } if (this.currentProfile.getRunInBackground()) { - Executors.newSingleThreadExecutor().execute(Server::startServers); + Executors.newSingleThreadExecutor().execute(ServerHandler::startServers); this.serverLauncherGUI.hideToTray(); } } diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java index 5956dc6..b270bb5 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java @@ -1,9 +1,9 @@ package net.knarcraft.minecraftserverlauncher.server; import net.knarcraft.minecraftserverlauncher.Main; -import net.knarcraft.minecraftserverlauncher.profile.Collection; import net.knarcraft.minecraftserverlauncher.profile.ServerLauncherController; import net.knarcraft.minecraftserverlauncher.server.servertypes.ServerType; +import net.knarcraft.minecraftserverlauncher.userinterface.ServerLauncherGUI; import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions; import javax.naming.ConfigurationException; @@ -31,14 +31,9 @@ import java.util.regex.Pattern; * @since 1.0.0 */ public class Server { - /** - * Available ram sizes. For ServerLauncherGUI combo - */ - private static final String[] ramList = {"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; - private final String name; private final ArrayList playerList; private String path; @@ -51,7 +46,7 @@ public class Server { private BufferedReader reader; private boolean started; private ScheduledExecutorService consoleOutputExecutor; - private static boolean stoppingServers = false; + private final ServerLauncherGUI gui = Main.getController().getGUI(); /** * Initializes a new server with default values @@ -65,7 +60,7 @@ public class Server { this.playerList = new ArrayList<>(); this.type = null; this.serverVersion = ""; - this.maxRam = ramList[0]; + this.maxRam = ServerHandler.getRamList()[0]; this.process = null; this.writer = null; this.reader = null; @@ -91,15 +86,6 @@ public class Server { this.playerList = new ArrayList<>(); } - /** - * Gets the list of available RAM choices allowed - * - * @return

All available RAM choices

- */ - public static String[] getRamList() { - return ramList; - } - /** * Gets the buffered reader used to read from this server * @@ -109,101 +95,6 @@ public class Server { return this.reader; } - /** - * Marks the servers as finished stopping when a stop is confirmed - */ - public static void serversStopped() { - if (stoppingServers) { - stoppingServers = false; - } - } - - /** - * Tries to stop all enabled servers - * - * @throws IOException

If a writer's process is already closed but not null

- */ - public static void stop() throws IOException, InterruptedException { - if (stoppingServers) { - killServers(); - return; - } - - stoppingServers = true; - for (Collection collection : Main.getController().getCurrentProfile().getCollections()) { - Server server = collection.getServer(); - if (server.writer != null) { - if (server.type.isProxy()) { - server.writer.write("end\n"); - } else { - server.writer.write("stop\n"); - } - server.writer.flush(); - server.writer = null; - server.started = false; - } - } - } - - /** - * Kills all server processes - * - * @throws InterruptedException

If interrupted waiting for any of the servers to stop

- */ - private static void killServers() throws InterruptedException { - for (Collection collection : Main.getController().getCurrentProfile().getCollections()) { - Server server = collection.getServer(); - killServer(server); - } - } - - /** - * Kills the given server after waiting 30 seconds for it to terminate normally - * - * @param server

The server to kill

- * @throws InterruptedException

If interrupted waiting for the server to stop

- */ - private static void killServer(Server server) throws InterruptedException { - if (server.process != null) { - if (!server.process.waitFor(30, TimeUnit.SECONDS)) { - server.process.destroyForcibly(); - server.process.waitFor(); - } - } - } - - /** - * Runs all enabled servers with their settings - */ - public static void startServers() { - ServerLauncherController controller = Main.getController(); - controller.getGUI().setStatus("Starting servers"); - int serverNum = 0; - for (Collection collection : controller.getCurrentProfile().getCollections()) { - if (!collection.getServer().runServer(serverNum++ == 0)) { - controller.getGUI().showError("An error occurred. Start aborted. Please check the BuildTools log."); - try { - Server.stop(); - } catch (IOException | InterruptedException e) { - e.printStackTrace(); - } - controller.getGUI().updateGUIElementsWhenServersStartOrStop(false); - return; - } - } - } - - /** - * Gets a server object from a server save string - * - * @param saveString

The string containing necessary data regarding the server

- * @return

A server in the same state it was saved in

- */ - public static Server fromString(String saveString) throws ConfigurationException { - String[] data = saveString.split(";"); - return new Server(data[0], data[1], Boolean.parseBoolean(data[2]), data[3], data[4], data[5]); - } - /** * Gets the name of the server * @@ -269,6 +160,42 @@ public class Server { } } + /** + * Gets whether this server is a proxy server + * + *

A proxy server is a server running BungeeCord, Waterfall or Travertine.

+ * + * @return

True if this server is a proxy server

+ */ + public boolean isProxy() { + return this.type.isProxy(); + } + + /** + * Marks this server as stopped + */ + public void setStopped() { + this.started = false; + } + + /** + * Gets the writer used to write to this server + * + * @return

The writer used.

+ */ + public BufferedWriter getWriter() { + return this.writer; + } + + /** + * Sets the writer used to write to this server + * + * @param writer

The new writer to use.

+ */ + public void setWriter(BufferedWriter writer) { + this.writer = writer; + } + /** * Gets the path for this server's files * @@ -374,7 +301,7 @@ public class Server { */ private void addPlayer(String name) { this.playerList.add(name); - Main.getController().getGUI().getServerControlTab().addPlayer(name); + gui.getServerControlTab().addPlayer(name); } /** @@ -384,7 +311,7 @@ public class Server { */ private void removePlayer(String name) { playerList.removeIf(player -> player.equals(name)); - Main.getController().getGUI().getServerControlTab().removePlayer(name); + gui.getServerControlTab().removePlayer(name); } /** @@ -401,8 +328,9 @@ public class Server { * * @return

True if nothing went wrong

*/ - private boolean runServer(boolean isFirstServer) { - if (stoppingServers) { + public boolean runServer(boolean isFirstServer) { + if (ServerHandler.stoppingServers()) { + gui.logMessage("Stopping servers. Cannot start yet."); return false; } //Ignore a disabled server @@ -412,20 +340,21 @@ public class Server { } //Tries to do necessary pre-start work if (!initializeJarDownload() || (!isFirstServer && !delayStartup())) { + gui.logError("Failed to perform startup tasks."); this.started = false; return false; } - if (stoppingServers) { + if (ServerHandler.stoppingServers()) { return false; } //Starts the server if possible try { startServerProcess(); - Main.getController().getGUI().setStatus("Servers are running"); + gui.setStatus("Servers are running"); this.started = true; return true; } catch (IOException e) { - Main.getController().getGUI().setStatus("Could not start server"); + gui.setStatus("Could not start server"); this.started = false; return false; } @@ -573,7 +502,7 @@ public class Server { */ private boolean delayStartup() { try { - Main.getController().getGUI().setStatus("Delaying startup"); + gui.setStatus("Delaying startup"); TimeUnit.SECONDS.sleep(Main.getController().getCurrentProfile().getDelayStartup()); return true; } catch (InterruptedException e) { @@ -589,18 +518,15 @@ public class Server { * @return

True if nothing went wrong

*/ private boolean initializeJarDownload() { - ServerLauncherController controller = Main.getController(); - if (!controller.getDownloadAllJars()) { - try { - controller.getGUI().setStatus("Downloading jar..."); - this.downloadJar(); - controller.getGUI().setStatus("File downloaded"); - } catch (IOException e) { - controller.getGUI().setStatus("Error: Jar file not found"); - e.printStackTrace(); - this.started = false; - return false; - } + try { + gui.setStatus("Downloading jar..."); + this.downloadJar(); + gui.setStatus("File downloaded"); + } catch (IOException e) { + gui.setStatus("Error: Jar file not found, not downloaded or not built."); + gui.logError("Unable to get required .jar file: " + e.getMessage()); + this.started = false; + return false; } return true; } diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/ServerHandler.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/ServerHandler.java new file mode 100644 index 0000000..4bf340c --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/ServerHandler.java @@ -0,0 +1,140 @@ +package net.knarcraft.minecraftserverlauncher.server; + +import net.knarcraft.minecraftserverlauncher.Main; +import net.knarcraft.minecraftserverlauncher.profile.Collection; +import net.knarcraft.minecraftserverlauncher.profile.ServerLauncherController; +import net.knarcraft.minecraftserverlauncher.userinterface.ServerLauncherGUI; + +import javax.naming.ConfigurationException; +import java.io.BufferedWriter; +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +public class ServerHandler { + + /** + * Available ram sizes. For ServerLauncherGUI combo + */ + private static final String[] ramList = {"512M", "1G", "2G", "3G", "4G", "5G", "6G", "7G", "8G", "9G", "10G", + "11G", "12G", "13G", "14G", "15G", "16G"}; + + private static boolean stoppingServers = false; + private static final ServerLauncherGUI gui = Main.getController().getGUI(); + + /** + * Gets the list of available RAM choices allowed + * + * @return

All available RAM choices

+ */ + public static String[] getRamList() { + return ramList; + } + + /** + * Gets whether the servers are currently in the process of stopping + * + * @return

True if the servers are in the process of stopping.

+ */ + public static boolean stoppingServers() { + return stoppingServers; + } + + /** + * Marks the servers as finished stopping when a stop is confirmed + */ + public static void serversStopped() { + if (stoppingServers) { + stoppingServers = false; + } + } + + /** + * Tries to stop all enabled servers + * + * @throws IOException

If a writer's process is already closed but not null

+ */ + public static void stop() throws IOException, InterruptedException { + if (stoppingServers) { + killServers(); + return; + } + + stoppingServers = true; + for (Collection collection : Main.getController().getCurrentProfile().getCollections()) { + Server server = collection.getServer(); + BufferedWriter writer = server.getWriter(); + if (writer != null) { + if (server.isProxy()) { + writer.write("end\n"); + } else { + writer.write("stop\n"); + } + writer.flush(); + server.setWriter(null); + server.setStopped(); + } + } + //TODO: Set stoppingServers to false if no servers are actually running + } + + /** + * Kills all server processes + * + * @throws InterruptedException

If interrupted waiting for any of the servers to stop

+ */ + private static void killServers() throws InterruptedException { + for (Collection collection : Main.getController().getCurrentProfile().getCollections()) { + Server server = collection.getServer(); + killServer(server); + } + } + + /** + * Kills the given server after waiting 30 seconds for it to terminate normally + * + * @param server

The server to kill

+ * @throws InterruptedException

If interrupted waiting for the server to stop

+ */ + private static void killServer(Server server) throws InterruptedException { + Process serverProcess = server.getProcess(); + if (serverProcess != null) { + if (!serverProcess.waitFor(30, TimeUnit.SECONDS)) { + serverProcess.destroyForcibly(); + serverProcess.waitFor(); + } + } + } + + /** + * Runs all enabled servers with their settings + */ + public static void startServers() { + ServerLauncherController controller = Main.getController(); + gui.setStatus("Starting servers"); + int serverNum = 0; + for (Collection collection : controller.getCurrentProfile().getCollections()) { + if (!collection.getServer().runServer(serverNum++ == 0)) { + gui.showError("An error occurred. Start aborted. Please check relevant log files."); + try { + stop(); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + gui.updateGUIElementsWhenServersStartOrStop(false); + return; + } + } + } + + /** + * Gets a server object from a server save string + * + * @param saveString

The string containing necessary data regarding the server

+ * @return

A server in the same state it was saved in

+ */ + public static Server fromString(String saveString) throws ConfigurationException { + String[] data = saveString.split(";"); + return new Server(data[0], data[1], Boolean.parseBoolean(data[2]), data[3], data[4], data[5]); + } + +} diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherGUI.java b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherGUI.java index 00449f8..4f43417 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherGUI.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherGUI.java @@ -3,7 +3,7 @@ package net.knarcraft.minecraftserverlauncher.userinterface; import net.knarcraft.minecraftserverlauncher.Main; import net.knarcraft.minecraftserverlauncher.profile.Collection; import net.knarcraft.minecraftserverlauncher.profile.ServerLauncherController; -import net.knarcraft.minecraftserverlauncher.server.Server; +import net.knarcraft.minecraftserverlauncher.server.ServerHandler; import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions; import javax.imageio.ImageIO; @@ -327,7 +327,7 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, private void handleMainTabButtons(Object actionSource) { if (actionSource == startServerButton) { controller.saveState(); - Executors.newSingleThreadExecutor().execute(Server::startServers); + Executors.newSingleThreadExecutor().execute(ServerHandler::startServers); } else if (actionSource == stopServerButton) { stopServers(); } else if (actionSource == addServerButton) { @@ -404,7 +404,7 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, public void stopServers() { try { setStatus("Servers are stopping..."); - Server.stop(); + ServerHandler.stop(); } catch (IOException e1) { showError("Could not stop server."); e1.printStackTrace(); diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerTab.java b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerTab.java index b972316..dc6957d 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerTab.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerTab.java @@ -1,7 +1,7 @@ package net.knarcraft.minecraftserverlauncher.userinterface; import net.knarcraft.minecraftserverlauncher.Main; -import net.knarcraft.minecraftserverlauncher.server.Server; +import net.knarcraft.minecraftserverlauncher.server.ServerHandler; import net.knarcraft.minecraftserverlauncher.server.ServerTypeHandler; import net.knarcraft.minecraftserverlauncher.server.servertypes.ServerType; @@ -76,7 +76,7 @@ public class ServerTab implements ActionListener { sl_panel_3.putConstraint(SpringLayout.WEST, lblMaxRam, 6, SpringLayout.EAST, serverTypes); panel.add(lblMaxRam); - maxRam = new JComboBox<>(Server.getRamList()); + maxRam = new JComboBox<>(ServerHandler.getRamList()); sl_panel_3.putConstraint(SpringLayout.NORTH, maxRam, 0, SpringLayout.NORTH, serverTypes); sl_panel_3.putConstraint(SpringLayout.WEST, maxRam, 6, SpringLayout.EAST, lblMaxRam); sl_panel_3.putConstraint(SpringLayout.EAST, maxRam, -10, SpringLayout.EAST, panel); diff --git a/src/test/java/net/knarcraft/minecraftserverlauncher/server/ServerTest.java b/src/test/java/net/knarcraft/minecraftserverlauncher/server/ServerTest.java index 75e7768..ac1202a 100644 --- a/src/test/java/net/knarcraft/minecraftserverlauncher/server/ServerTest.java +++ b/src/test/java/net/knarcraft/minecraftserverlauncher/server/ServerTest.java @@ -11,7 +11,7 @@ public class ServerTest { @Test public void fromStringTest() throws ConfigurationException { - Server server = Server.fromString("asd;/home/;false;Bukkit;1.10.2;4G;"); + Server server = ServerHandler.fromString("asd;/home/;false;Bukkit;1.10.2;4G;"); assertEquals("asd", server.getName()); assertEquals("/home/", server.getPath()); assertFalse(server.isEnabled());