Fixes some bugs preventing servers from starting
All checks were successful
KnarCraft/Minecraft-Server-Launcher/pipeline/head This commit looks good

This commit is contained in:
Kristian Knarvik 2020-08-07 04:08:05 +02:00
parent b144bbb903
commit a2d4d491ba
4 changed files with 158 additions and 81 deletions

View File

@ -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++;
}
}

View File

@ -48,6 +48,11 @@ public class Server {
private final String bungeeVersion;
private boolean started;
/**
* Initializes a new server with default values
*
* @param name <p>The name of the server</p>
*/
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 <p>The name of the server</p>
* @param path <p>The file path of the folder containing the server files</p>
* @param enabled <p>Whether the server is enabled to start the next time servers are started</p>
* @param typeName <p>The name of the server type currently in use on the server</p>
* @param serverVersion <p>The currently selected server version for the given server type</p>
* @param maxRam <p>The maximum amount of ram the server is allowed to use</p>
* @param vanillaVersion <p>The version of the "latest" downloaded vanilla version</p>
* @param snapshotVersion <p>The version of the "latest" downloaded snapshot version</p>
* @param spongeVanillaVersion <p>The version of the "latest" SpongeVanilla jar downloaded</p>
* @param bungeeVersion <p>The version of the "latest" bungee jar downloaded</p>
*/
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 <p>The name of the server</p>
*/
public String getName() {
return this.name;
}
/**
* Whether the server has been started
*
* @return <p>True if the server has been started. False otherwise</p>
*/
public boolean isStarted() {
return started;
}
/**
* Gets the name of the server type used by this server
*
* @return <p>The name of the server type used by this server</p>
*/
public String getTypeName() {
return this.type.getName();
}
/**
* Gets the version used given server type used
*
* @return <p>The server version given server type</p>
*/
public String getServerVersion() {
return this.serverVersion;
}
@ -255,76 +294,39 @@ public class Server {
}
/**
* Runs the Minecraft server.
* Runs a Minecraft server
*
* @return <p>True if nothing went wrong</p>
*/
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 <p>The server output</p>
* @throws IOException <p>If reading from the reader fails</p>
*/
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 <p>If the process cannot be started</p>
*/
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 <p>True if the delay was successful</p>
*/
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 <p>True if nothing went wrong</p>
*/
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 <p>If the file was not found and could not be acquired</p>
*/
private void downloadJar() throws IOException {
String path = this.path + File.separator;

View File

@ -54,7 +54,7 @@ public class Vanilla extends AbstractServerType {
* Gets the URL to the .jar file for the newest version
*
* @return <p>An array containing the latest version and a link to its file</p>
* @throws IOException <p>If the remote resource cannot be read</p>
* @throws IOException <p>If the remote resource cannot be readFromServer</p>
*/
private String[] getLatestFile() throws IOException {
String versionText = readFile(versionURL);
@ -70,7 +70,7 @@ public class Vanilla extends AbstractServerType {
*
* @param versionURL <p>The URL to the version document describing the .jar file</p>
* @return <p>The URL necessary do download the .jar file</p>
* @throws IOException <p>If the remote resource cannot be read</p>
* @throws IOException <p>If the remote resource cannot be readFromServer</p>
*/
private String getVanillaDownloadURL(String versionURL) throws IOException {
String versionText = readFile(versionURL);

View File

@ -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 <kristian.knarvik@knett.no>
* @version 1.0.0
* @since 1.0.0
* @author Kristian Knarvik <kristian.knarvik@knett.no>
* @version 1.0.0
* @since 1.0.0
*/
public class CommonFunctions {
/**
* Gets a resource as an InputStream
*
* @param resourceName <p>The name of the resource you want to read</p>
* @param resourceName <p>The name of the resource you want to readFromServer</p>
* @return <p>An input stream which can be used to access the resource</p>
*/
public static InputStream getResourceAsStream(String resourceName) {
@ -34,8 +40,8 @@ public class CommonFunctions {
/**
* Gets a resource as a Scanner
*
* @param resourceName <p>The name of the resource you want to read</p>
* @return <p>A scanner which can be used to read contents of the resource</p>
* @param resourceName <p>The name of the resource you want to readFromServer</p>
* @return <p>A scanner which can be used to readFromServer contents of the resource</p>
* @throws FileNotFoundException <p>If the resource is not found</p>
*/
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 <p>The string containing the substrings</p>
* @param start <p>The substring before the wanted substring</p>
* @param end <p>The substring after the wanted substring</p>
* @param start <p>The substring before the wanted substring</p>
* @param end <p>The substring after the wanted substring</p>
* @return <p>The wanted substring</p>
*/
public static String stringBetween(String string, String start, String end) {
@ -67,7 +73,7 @@ public class CommonFunctions {
*
* <p>This is used to find the newest version of jars and the software.</p>
*
* @param path <p>The full url of the file to read</p>
* @param path <p>The full url of the file to readFromServer</p>
* @return <p>True if successful. False otherwise</p>
*/
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 <p>The full url of the file to download</p>
* @param path <p>The full url of the file to download</p>
* @param outfile <p>The file to save to</p>
* @return <p>True if successful. False otherwise</p>
*/
@ -96,7 +102,7 @@ public class CommonFunctions {
/**
* Recursively copies a folder to another location
*
* @param source <p>The folder to copy</p>
* @param source <p>The folder to copy</p>
* @param destination <p>Target destination</p>
* @throws IOException <p>If we can't start a file stream</p>
*/
@ -124,8 +130,8 @@ public class CommonFunctions {
* Copies a file from one location to another
*
* @param serverLauncherGui <p>The serverLauncherGui to use for alerting the user</p>
* @param source <p>The file to copy</p>
* @param destination <p>The location of the copied file</p>
* @param source <p>The file to copy</p>
* @param destination <p>The location of the copied file</p>
* @throws IOException <p>If reading or writing fails</p>
*/
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 <p>The URL to open</p>
*/
public static void goToURL(String url) {