From 32544813267d5bdc3225f09e3c9c625df2c5eb67 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 5 Feb 2021 18:41:54 +0100 Subject: [PATCH] Improves server waiting and killing Makes the client force stop servers if the stop button is clicked more than once Prevents new servers from starting after server stop is initialized --- .../minecraftserverlauncher/Main.java | 2 + .../server/Server.java | 59 ++++++++++++++++--- .../userinterface/ServerLauncherGUI.java | 3 + 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java b/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java index 60a588e..eab5d0c 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java @@ -2,6 +2,7 @@ package net.knarcraft.minecraftserverlauncher; import net.knarcraft.minecraftserverlauncher.profile.Collection; import net.knarcraft.minecraftserverlauncher.profile.Controller; +import net.knarcraft.minecraftserverlauncher.server.Server; import net.knarcraft.minecraftserverlauncher.userinterface.ServerConsoles; import net.knarcraft.minecraftserverlauncher.userinterface.ServerLauncherGUI; import net.knarcraft.minecraftserverlauncher.utility.Updater; @@ -85,6 +86,7 @@ public class Main { boolean runningNew = serversRunning(); if (serversAreRunning && !runningNew) { //Servers stopped running + Server.serversStopped(); gui.updateGUIElementsWhenServersStartOrStop(false); gui.setStatus("Servers are stopped"); } else if (!serversAreRunning && runningNew) { diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java index 4692b26..7f4addb 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java @@ -22,8 +22,6 @@ import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.stringBetween; - /** * Contains all necessary information to create, runServer and manage a Minecraft server. @@ -53,6 +51,7 @@ public class Server { private BufferedReader reader; private boolean started; private ScheduledExecutorService consoleOutputExecutor; + private static boolean stoppingServers = false; /** * Initializes a new server with default values @@ -110,12 +109,27 @@ 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 { + 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) { @@ -131,6 +145,31 @@ public class Server { } } + /** + * 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 */ @@ -143,7 +182,7 @@ public class Server { controller.getGUI().setStatus("An error occurred. Start aborted"); try { Server.stop(); - } catch (IOException e) { + } catch (IOException | InterruptedException e) { e.printStackTrace(); } controller.getGUI().updateGUIElementsWhenServersStartOrStop(false); @@ -283,9 +322,9 @@ public class Server { } /** - * Checks whether this server is fully stopped + * Removes all information about the server's process, writer and reader */ - private void stopped() { + private void cleanStoppedServerValues() { consoleOutputExecutor.shutdown(); process = null; writer = null; @@ -361,6 +400,9 @@ public class Server { * @return

True if nothing went wrong

*/ private boolean runServer(boolean isFirstServer) { + if (stoppingServers) { + return false; + } //Ignore a disabled server if (!this.enabled) { this.started = false; @@ -371,6 +413,9 @@ public class Server { this.started = false; return false; } + if (stoppingServers) { + return false; + } //Starts the server if possible try { startServerProcess(); @@ -430,7 +475,7 @@ public class Server { updatePlayerList(readText); } if (!getProcess().isAlive()) { - stopped(); + cleanStoppedServerValues(); } } diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherGUI.java b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherGUI.java index 9aef608..d83f8bb 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherGUI.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherGUI.java @@ -401,6 +401,9 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, } catch (IOException e1) { showError("Could not stop server."); e1.printStackTrace(); + } catch (InterruptedException e) { + showError("Could not kill server."); + e.printStackTrace(); } }