Improves server waiting and killing
All checks were successful
KnarCraft/Minecraft-Server-Launcher/pipeline/head This commit looks good

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
This commit is contained in:
Kristian Knarvik 2021-02-05 18:41:54 +01:00
parent fb705f4e13
commit 3254481326
3 changed files with 57 additions and 7 deletions

View File

@ -2,6 +2,7 @@ package net.knarcraft.minecraftserverlauncher;
import net.knarcraft.minecraftserverlauncher.profile.Collection; import net.knarcraft.minecraftserverlauncher.profile.Collection;
import net.knarcraft.minecraftserverlauncher.profile.Controller; import net.knarcraft.minecraftserverlauncher.profile.Controller;
import net.knarcraft.minecraftserverlauncher.server.Server;
import net.knarcraft.minecraftserverlauncher.userinterface.ServerConsoles; import net.knarcraft.minecraftserverlauncher.userinterface.ServerConsoles;
import net.knarcraft.minecraftserverlauncher.userinterface.ServerLauncherGUI; import net.knarcraft.minecraftserverlauncher.userinterface.ServerLauncherGUI;
import net.knarcraft.minecraftserverlauncher.utility.Updater; import net.knarcraft.minecraftserverlauncher.utility.Updater;
@ -85,6 +86,7 @@ public class Main {
boolean runningNew = serversRunning(); boolean runningNew = serversRunning();
if (serversAreRunning && !runningNew) { if (serversAreRunning && !runningNew) {
//Servers stopped running //Servers stopped running
Server.serversStopped();
gui.updateGUIElementsWhenServersStartOrStop(false); gui.updateGUIElementsWhenServersStartOrStop(false);
gui.setStatus("Servers are stopped"); gui.setStatus("Servers are stopped");
} else if (!serversAreRunning && runningNew) { } else if (!serversAreRunning && runningNew) {

View File

@ -22,8 +22,6 @@ import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; 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. * Contains all necessary information to create, runServer and manage a Minecraft server.
@ -53,6 +51,7 @@ public class Server {
private BufferedReader reader; private BufferedReader reader;
private boolean started; private boolean started;
private ScheduledExecutorService consoleOutputExecutor; private ScheduledExecutorService consoleOutputExecutor;
private static boolean stoppingServers = false;
/** /**
* Initializes a new server with default values * Initializes a new server with default values
@ -110,12 +109,27 @@ public class Server {
return this.reader; 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 * Tries to stop all enabled servers
* *
* @throws IOException <p>If a writer's process is already closed but not null</p> * @throws IOException <p>If a writer's process is already closed but not null</p>
*/ */
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()) { for (Collection collection : Main.getController().getCurrentProfile().getCollections()) {
Server server = collection.getServer(); Server server = collection.getServer();
if (server.writer != null) { if (server.writer != null) {
@ -131,6 +145,31 @@ public class Server {
} }
} }
/**
* Kills all server processes
* @throws InterruptedException <p>If interrupted waiting for any of the servers to stop</p>
*/
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 <p>The server to kill</p>
* @throws InterruptedException <p>If interrupted waiting for the server to stop</p>
*/
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 * Runs all enabled servers with their settings
*/ */
@ -143,7 +182,7 @@ public class Server {
controller.getGUI().setStatus("An error occurred. Start aborted"); controller.getGUI().setStatus("An error occurred. Start aborted");
try { try {
Server.stop(); Server.stop();
} catch (IOException e) { } catch (IOException | InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
controller.getGUI().updateGUIElementsWhenServersStartOrStop(false); 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(); consoleOutputExecutor.shutdown();
process = null; process = null;
writer = null; writer = null;
@ -361,6 +400,9 @@ public class Server {
* @return <p>True if nothing went wrong</p> * @return <p>True if nothing went wrong</p>
*/ */
private boolean runServer(boolean isFirstServer) { private boolean runServer(boolean isFirstServer) {
if (stoppingServers) {
return false;
}
//Ignore a disabled server //Ignore a disabled server
if (!this.enabled) { if (!this.enabled) {
this.started = false; this.started = false;
@ -371,6 +413,9 @@ public class Server {
this.started = false; this.started = false;
return false; return false;
} }
if (stoppingServers) {
return false;
}
//Starts the server if possible //Starts the server if possible
try { try {
startServerProcess(); startServerProcess();
@ -430,7 +475,7 @@ public class Server {
updatePlayerList(readText); updatePlayerList(readText);
} }
if (!getProcess().isAlive()) { if (!getProcess().isAlive()) {
stopped(); cleanStoppedServerValues();
} }
} }

View File

@ -401,6 +401,9 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener,
} catch (IOException e1) { } catch (IOException e1) {
showError("Could not stop server."); showError("Could not stop server.");
e1.printStackTrace(); e1.printStackTrace();
} catch (InterruptedException e) {
showError("Could not kill server.");
e.printStackTrace();
} }
} }