Adds various fixes to make the two java versions work as expected

Makes it possible to load a controller without generating a GUI, for better testing
Makes sure not to try and parse empty profile lines
Saves controller settings in a more readable and appendable format
Adds code for using the correct java version for the occasion
Adds a new function for writing to files
This commit is contained in:
Kristian Knarvik 2021-08-02 21:06:22 +02:00
parent 6ec44f1f92
commit f1eead3807
21 changed files with 350 additions and 136 deletions

View File

@ -1,7 +1,7 @@
package net.knarcraft.minecraftserverlauncher; 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.ServerLauncherController;
import net.knarcraft.minecraftserverlauncher.server.Server; 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;
@ -28,7 +28,7 @@ import java.util.concurrent.TimeUnit;
public class Main { public class Main {
private static final String updateChannel = "beta"; private static final String updateChannel = "beta";
private static final String updateURL = "https://api.knarcraft.net/minecraftserverlauncher"; private static final String updateURL = "https://api.knarcraft.net/minecraftserverlauncher";
private static final Controller controller = Controller.getInstance(); private static final ServerLauncherController controller = ServerLauncherController.getInstance();
private static String applicationWorkDirectory; private static String applicationWorkDirectory;
private static boolean serversAreRunning = false; private static boolean serversAreRunning = false;
private static ServerLauncherGUI gui; private static ServerLauncherGUI gui;
@ -42,7 +42,7 @@ public class Main {
} }
EventQueue.invokeLater(() -> { EventQueue.invokeLater(() -> {
try { try {
new ServerConsoles(); ServerConsoles.instantiate();
controller.loadState(); controller.loadState();
gui = controller.getGUI(); gui = controller.getGUI();
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor(); ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
@ -58,7 +58,7 @@ public class Main {
* *
* @return <p>The controller used by the software</p> * @return <p>The controller used by the software</p>
*/ */
public static Controller getController() { public static ServerLauncherController getController() {
return controller; return controller;
} }

View File

@ -8,7 +8,7 @@ import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
import javax.swing.*; import javax.swing.*;
import java.io.*; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
/** /**
@ -230,7 +230,9 @@ public class Profile {
*/ */
public static Profile fromString(String profileString) throws ConfigurationException { public static Profile fromString(String profileString) throws ConfigurationException {
Profile profile; Profile profile;
if (profileString.contains("?")) { if (profileString.equals("")) {
return null;
} else if (profileString.contains("?")) {
String[] data = profileString.split("\\?"); String[] data = profileString.split("\\?");
String[] profileData = data[0].split(";", -1); String[] profileData = data[0].split(";", -1);
profile = parseProfile(profileData); profile = parseProfile(profileData);

View File

@ -9,16 +9,20 @@ import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions;
import net.knarcraft.minecraftserverlauncher.utility.JarDownloader; import net.knarcraft.minecraftserverlauncher.utility.JarDownloader;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
import java.io.*; import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Scanner; import java.util.Scanner;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
/** /**
* This class handles profiles, GUI creation and session restoration * This class handles profiles, GUI creation and session restoration
*/ */
public class Controller { public class ServerLauncherController {
private final String workingDirectory = Main.getApplicationWorkDirectory() + File.separator + "files"; private final String workingDirectory = Main.getApplicationWorkDirectory() + File.separator + "files";
private final String profilesFile = workingDirectory + File.separator + "Profiles.txt"; private final String profilesFile = workingDirectory + File.separator + "Profiles.txt";
@ -28,12 +32,14 @@ public class Controller {
private ServerLauncherGUI serverLauncherGUI; private ServerLauncherGUI serverLauncherGUI;
private Profile currentProfile; private Profile currentProfile;
private boolean downloadAllJars; private boolean downloadAllJars;
private static Controller controller; private static ServerLauncherController controller;
private String javaCommand = "java";
private String oldJavaCommand = "java";
/** /**
* Instantiates a new controller * Instantiates a new controller
*/ */
private Controller() { private ServerLauncherController() {
this.profileList = new ArrayList<>(); this.profileList = new ArrayList<>();
} }
@ -42,9 +48,9 @@ public class Controller {
* *
* @return <p>An instance of the controller</p> * @return <p>An instance of the controller</p>
*/ */
public static Controller getInstance() { public static ServerLauncherController getInstance() {
if (controller == null) { if (controller == null) {
controller = new Controller(); controller = new ServerLauncherController();
} }
return controller; return controller;
} }
@ -85,6 +91,29 @@ public class Controller {
return currentProfile.getDelayStartup(); return currentProfile.getDelayStartup();
} }
/**
* Gets the command for running java
*
* <p>To play on the newest version of Minecraft, this needs to be JDK 16. Can be just "java" or a file path.</p>
*
* @return <p>The command for running java</p>
*/
public String getJavaCommand() {
return javaCommand;
}
/**
* Gets the command for running older versions of java
*
* <p>The command used to run older minecraft server versions. JRE 8 should probably work.
* Can be just "java" or a file path.</p>
*
* @return <p>The command for running older versions of java</p>
*/
public String getOldJavaCommand() {
return oldJavaCommand;
}
@Override @Override
public String toString() { public String toString() {
int guiWidth; int guiWidth;
@ -96,7 +125,8 @@ public class Controller {
guiWidth = serverLauncherGUI.getSize().width; guiWidth = serverLauncherGUI.getSize().width;
guiHeight = serverLauncherGUI.getSize().height; guiHeight = serverLauncherGUI.getSize().height;
} }
return String.format("%s;%d;%d;%b", currentProfile.getName(), guiWidth, guiHeight, downloadAllJars); return String.format("selectedProfile;%s\nguiWidth;%d\nguiHeight;%d\ndownloadAllJars;%b\njavaCommand;%s\noldJavaCommand;%s",
currentProfile.getName(), guiWidth, guiHeight, downloadAllJars, javaCommand, oldJavaCommand);
} }
/** /**
@ -171,37 +201,122 @@ public class Controller {
} }
/** /**
* Loads data about the controller from a save string * Sets the download all jars option
* *
* @param data <p>The save string to load</p> * @param downloadAllJars <p>Whether to download all jars</p>
* @return <p>The currently selected profile</p>
* @throws IOException <p>If unable to create the GUI</p>
*/ */
private String fromString(String data) throws IOException { public void setDownloadAllJars(boolean downloadAllJars) {
String[] dataList = data.split(";"); this.downloadAllJars = downloadAllJars;
this.downloadAllJars = Boolean.parseBoolean(dataList[3]); }
this.serverLauncherGUI = new ServerLauncherGUI(Integer.parseInt(dataList[1]), Integer.parseInt(dataList[2]));
return dataList[0]; /**
* Sets the currently selected profile
*
* @param profileName <p>The name of the currently selected profile</p>
*/
public void setCurrentProfile(String profileName) {
this.currentProfile = getProfileByName(profileName);
}
/**
* Saves the state of the entire application to disk
*/
public void saveState() {
saveGUIStateToServer();
try {
CommonFunctions.createAllFolders();
CommonFunctions.writeFile(mainFile, this.toString());
StringBuilder builder = new StringBuilder();
for (Profile profile : profileList) {
builder.append(profile.toString()).append("\n");
}
CommonFunctions.writeFile(profilesFile, builder.toString());
} catch (IOException e) {
serverLauncherGUI.showError("Unable to save data.");
e.printStackTrace();
}
} }
/** /**
* Reads profiles and servers from a text file * Reads profiles and servers from a text file
*/ */
public void loadState() throws ConfigurationException, IOException { public void loadState() throws ConfigurationException, IOException {
loadState(false);
}
/**
* Reads profiles and servers from a text file
*
* @param silent <p>If silent, no GUI will be created</p>
*/
public void loadState(boolean silent) throws ConfigurationException, IOException {
//Loads data regarding this controller //Loads data regarding this controller
String currentProfile = null; String currentProfile = null;
if (new File(mainFile).exists()) { if (new File(mainFile).exists()) {
String controllerData = CommonFunctions.readFile(mainFile); currentProfile = this.fromString(silent);
currentProfile = this.fromString(controllerData); } else if (!silent) {
} else {
this.serverLauncherGUI = new ServerLauncherGUI(); this.serverLauncherGUI = new ServerLauncherGUI();
} }
if (silent) {
return;
}
//Loads all saved profiles //Loads all saved profiles
loadProfiles(currentProfile); loadProfiles(currentProfile);
//Makes the GUI show the loaded data //Makes the GUI show the loaded data
executeGUILoadingTasks(); executeGUILoadingTasks();
} }
/**
* Loads data about the controller from a save string
*
* @param silent <p>If silent, no GUI will be created</p>
* @return <p>The currently selected profile</p>
*/
private String fromString(boolean silent) {
Map<String, String> loadedData = new HashMap<>();
try {
String currentData = CommonFunctions.readFile(mainFile);
for (String line : currentData.split("\n")) {
parseSaveLine(loadedData, line);
}
this.downloadAllJars = Boolean.parseBoolean(loadedData.get("downloadAllJars"));
if (!silent) {
this.serverLauncherGUI = new ServerLauncherGUI(Integer.parseInt(loadedData.get("guiWidth")),
Integer.parseInt(loadedData.get("guiHeight")));
} else {
this.serverLauncherGUI = new ServerLauncherGUI(true);
}
if (loadedData.get("javaCommand") != null) {
this.javaCommand = loadedData.get("javaCommand");
}
if (loadedData.get("oldJavaCommand") != null) {
this.oldJavaCommand = loadedData.get("oldJavaCommand");
}
return loadedData.get("selectedProfile");
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
/**
* Saves one config line to the provided map
*
* @param loadedData <p>The map to save the loaded configuration to</p>
* @param line <p>The line to read</p>
*/
private void parseSaveLine(Map<String, String> loadedData, String line) {
String[] lineData = line.split(";");
if (lineData.length != 2) {
return;
}
loadedData.put(lineData[0], lineData[1]);
}
/** /**
* Loads all saved profiles * Loads all saved profiles
* *
@ -213,6 +328,9 @@ public class Controller {
while (in.hasNextLine()) { while (in.hasNextLine()) {
String profileData = in.nextLine(); String profileData = in.nextLine();
Profile loadedProfile = Profile.fromString(profileData); Profile loadedProfile = Profile.fromString(profileData);
if (loadedProfile == null) {
continue;
}
profileList.add(loadedProfile); profileList.add(loadedProfile);
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
@ -248,45 +366,6 @@ public class Controller {
} }
} }
/**
* Sets the download all jars option
*
* @param downloadAllJars <p>Whether to download all jars</p>
*/
public void setDownloadAllJars(boolean downloadAllJars) {
this.downloadAllJars = downloadAllJars;
}
/**
* Sets the currently selected profile
*
* @param profileName <p>The name of the currently selected profile</p>
*/
public void setCurrentProfile(String profileName) {
this.currentProfile = getProfileByName(profileName);
}
/**
* Saves the state of the entire application to disk
*/
public void saveState() {
saveGUIStateToServer();
try {
CommonFunctions.createAllFolders();
PrintWriter mFile = new PrintWriter(mainFile);
mFile.println(this);
mFile.close();
PrintWriter pFile = new PrintWriter(profilesFile);
for (Profile profile : profileList) {
pFile.println(profile.toString());
}
pFile.close();
} catch (FileNotFoundException e) {
serverLauncherGUI.showError("Unable to save data.");
e.printStackTrace();
}
}
/** /**
* Updates the server object with the current state of the GUI server tab * Updates the server object with the current state of the GUI server tab
*/ */

View File

@ -2,7 +2,7 @@ package net.knarcraft.minecraftserverlauncher.server;
import net.knarcraft.minecraftserverlauncher.Main; import net.knarcraft.minecraftserverlauncher.Main;
import net.knarcraft.minecraftserverlauncher.profile.Collection; import net.knarcraft.minecraftserverlauncher.profile.Collection;
import net.knarcraft.minecraftserverlauncher.profile.Controller; import net.knarcraft.minecraftserverlauncher.profile.ServerLauncherController;
import net.knarcraft.minecraftserverlauncher.server.servertypes.ServerType; import net.knarcraft.minecraftserverlauncher.server.servertypes.ServerType;
import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions; import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions;
@ -147,6 +147,7 @@ public class Server {
/** /**
* Kills all server processes * Kills all server processes
*
* @throws InterruptedException <p>If interrupted waiting for any of the servers to stop</p> * @throws InterruptedException <p>If interrupted waiting for any of the servers to stop</p>
*/ */
private static void killServers() throws InterruptedException { private static void killServers() throws InterruptedException {
@ -158,6 +159,7 @@ public class Server {
/** /**
* Kills the given server after waiting 30 seconds for it to terminate normally * Kills the given server after waiting 30 seconds for it to terminate normally
*
* @param server <p>The server to kill</p> * @param server <p>The server to kill</p>
* @throws InterruptedException <p>If interrupted waiting for the server to stop</p> * @throws InterruptedException <p>If interrupted waiting for the server to stop</p>
*/ */
@ -174,7 +176,7 @@ public class Server {
* Runs all enabled servers with their settings * Runs all enabled servers with their settings
*/ */
public static void startServers() { public static void startServers() {
Controller controller = Main.getController(); ServerLauncherController controller = Main.getController();
controller.getGUI().setStatus("Starting servers"); controller.getGUI().setStatus("Starting servers");
int serverNum = 0; int serverNum = 0;
for (Collection collection : controller.getCurrentProfile().getCollections()) { for (Collection collection : controller.getCurrentProfile().getCollections()) {
@ -429,6 +431,23 @@ public class Server {
} }
} }
/**
* Gets the correct java command to use for the selected server version
*
* @return <p>The java version to run</p>
*/
private String getJavaCommand() {
ServerLauncherController controller = ServerLauncherController.getInstance();
if (serverVersion.toLowerCase().contains("latest")) {
return controller.getJavaCommand();
} else if (serverVersion.contains(".") && serverVersion.split("\\.").length >= 2 &&
Integer.parseInt(serverVersion.split("\\.")[1]) >= 17) {
return controller.getJavaCommand();
} else {
return controller.getOldJavaCommand();
}
}
/** /**
* Starts the process running this server * Starts the process running this server
* *
@ -443,7 +462,7 @@ public class Server {
} else { } else {
serverPath = jarDirectory + this.type.getName() + serverVersion + ".jar"; serverPath = jarDirectory + this.type.getName() + serverVersion + ".jar";
} }
builder = new ProcessBuilder("java", "-Xmx" + this.maxRam, "-Xms512M", builder = new ProcessBuilder(getJavaCommand(), "-Xmx" + this.maxRam, "-Xms512M",
"-Djline.terminal=jline.UnsupportedTerminal", "-Dcom.mojang.eula.agree=true", "-jar", serverPath, "-Djline.terminal=jline.UnsupportedTerminal", "-Dcom.mojang.eula.agree=true", "-jar", serverPath,
"nogui"); "nogui");
builder.directory(new File(this.path)); builder.directory(new File(this.path));
@ -532,6 +551,7 @@ public class Server {
/** /**
* Returns the first regex capture group found in a pattern * Returns the first regex capture group found in a pattern
*
* @param pattern <p>The regex pattern to use</p> * @param pattern <p>The regex pattern to use</p>
* @param text <p>The string to execute the pattern on</p> * @param text <p>The string to execute the pattern on</p>
* @return <p>The first capture group if a match is found. An empty string otherwise</p> * @return <p>The first capture group if a match is found. An empty string otherwise</p>
@ -569,7 +589,7 @@ public class Server {
* @return <p>True if nothing went wrong</p> * @return <p>True if nothing went wrong</p>
*/ */
private boolean initializeJarDownload() { private boolean initializeJarDownload() {
Controller controller = Main.getController(); ServerLauncherController controller = Main.getController();
if (!controller.getDownloadAllJars()) { if (!controller.getDownloadAllJars()) {
try { try {
controller.getGUI().setStatus("Downloading jar..."); controller.getGUI().setStatus("Downloading jar...");

View File

@ -1,6 +1,17 @@
package net.knarcraft.minecraftserverlauncher.server; package net.knarcraft.minecraftserverlauncher.server;
import net.knarcraft.minecraftserverlauncher.server.servertypes.*; import net.knarcraft.minecraftserverlauncher.server.servertypes.BungeeCord;
import net.knarcraft.minecraftserverlauncher.server.servertypes.CraftBukkit;
import net.knarcraft.minecraftserverlauncher.server.servertypes.Custom;
import net.knarcraft.minecraftserverlauncher.server.servertypes.MCPCPlus;
import net.knarcraft.minecraftserverlauncher.server.servertypes.Paper;
import net.knarcraft.minecraftserverlauncher.server.servertypes.ServerType;
import net.knarcraft.minecraftserverlauncher.server.servertypes.Spigot;
import net.knarcraft.minecraftserverlauncher.server.servertypes.SpongeForge;
import net.knarcraft.minecraftserverlauncher.server.servertypes.SpongeVanilla;
import net.knarcraft.minecraftserverlauncher.server.servertypes.Travertine;
import net.knarcraft.minecraftserverlauncher.server.servertypes.Vanilla;
import net.knarcraft.minecraftserverlauncher.server.servertypes.Waterfall;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;

View File

@ -3,7 +3,10 @@ package net.knarcraft.minecraftserverlauncher.server;
import net.knarcraft.minecraftserverlauncher.Main; import net.knarcraft.minecraftserverlauncher.Main;
import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions; import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions;
import java.io.*; import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -122,8 +125,8 @@ public class ServerVersionContainer {
if (!new File(versionFile).exists()) { if (!new File(versionFile).exists()) {
return; return;
} }
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(versionFile)))) { try {
String currentData = CommonFunctions.readBufferedReader(reader); String currentData = CommonFunctions.readFile(versionFile);
for (String line : currentData.split("\n")) { for (String line : currentData.split("\n")) {
parseSaveLine(line); parseSaveLine(line);
} }
@ -180,7 +183,7 @@ public class ServerVersionContainer {
* @param targetMap <p>The map to update</p> * @param targetMap <p>The map to update</p>
* @param data <p>The data string to parse</p> * @param data <p>The data string to parse</p>
*/ */
private void parseVersionsToMap(Map<String,String> targetMap, String data) { private void parseVersionsToMap(Map<String, String> targetMap, String data) {
String[] versions = data.split(","); String[] versions = data.split(",");
for (String version : versions) { for (String version : versions) {
String[] versionData = version.split("!"); String[] versionData = version.split("!");

View File

@ -20,8 +20,8 @@ public class SpongeVanilla extends AbstractServerType {
private final String srcStart; private final String srcStart;
private final String srcEnd; private final String srcEnd;
private final String downloadURLPart; private final String downloadURLPart;
Function<String,String> oldVersionFunction; Function<String, String> oldVersionFunction;
BiConsumer<String,String> versionUpdateFunction; BiConsumer<String, String> versionUpdateFunction;
final ServerVersionContainer serverVersionContainer; final ServerVersionContainer serverVersionContainer;
/** /**

View File

@ -5,7 +5,11 @@ import net.knarcraft.minecraftserverlauncher.Main;
import javax.swing.*; import javax.swing.*;
import javax.swing.text.DefaultCaret; import javax.swing.text.DefaultCaret;
import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList; import java.util.ArrayList;
import static javax.swing.text.DefaultCaret.ALWAYS_UPDATE; import static javax.swing.text.DefaultCaret.ALWAYS_UPDATE;
@ -77,6 +81,7 @@ public class Console extends KeyAdapter implements ActionListener, KeyListener {
/** /**
* Truncates the first 50 lines if the console output has reached the max limit * Truncates the first 50 lines if the console output has reached the max limit
*
* @param outputLines <p>The currently readable lines in the console output field</p> * @param outputLines <p>The currently readable lines in the console output field</p>
*/ */
private void truncateConsole(int outputLines) { private void truncateConsole(int outputLines) {

View File

@ -17,16 +17,22 @@ public class ServerConsoles {
private static JFrame frame; private static JFrame frame;
private static JTabbedPane consolesTabbedPane; private static JTabbedPane consolesTabbedPane;
private ServerConsoles() {
}
/** /**
* Initializes the server consoles frame * Initializes the server consoles frame
*/ */
public ServerConsoles() { public static void instantiate() {
if (frame == null || consolesTabbedPane == null) {
frame = new JFrame(); frame = new JFrame();
frame.setBounds(100, 100, 450, 300); frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
consolesTabbedPane = new JTabbedPane(JTabbedPane.TOP); consolesTabbedPane = new JTabbedPane(JTabbedPane.TOP);
frame.getContentPane().add(consolesTabbedPane, BorderLayout.CENTER); frame.getContentPane().add(consolesTabbedPane, BorderLayout.CENTER);
} }
}
/** /**
* Adds a new console tab * Adds a new console tab

View File

@ -1,7 +1,7 @@
package net.knarcraft.minecraftserverlauncher.userinterface; package net.knarcraft.minecraftserverlauncher.userinterface;
import net.knarcraft.minecraftserverlauncher.profile.Collection; import net.knarcraft.minecraftserverlauncher.profile.Collection;
import net.knarcraft.minecraftserverlauncher.profile.Controller; import net.knarcraft.minecraftserverlauncher.profile.ServerLauncherController;
import javax.swing.*; import javax.swing.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
@ -25,7 +25,7 @@ public class ServerControlTab implements ActionListener {
private JButton showConsolesButton; private JButton showConsolesButton;
private JTextField customCommandTextField; private JTextField customCommandTextField;
private Controller controller = Controller.getInstance(); private final ServerLauncherController controller = ServerLauncherController.getInstance();
private final ArrayList<String> globalPlayers; private final ArrayList<String> globalPlayers;
/** /**
@ -149,7 +149,7 @@ public class ServerControlTab implements ActionListener {
public void update() { public void update() {
this.targetServerCombo.removeAllItems(); this.targetServerCombo.removeAllItems();
this.targetServerCombo.addItem("All"); this.targetServerCombo.addItem("All");
for (Collection collection : Controller.getInstance().getCurrentProfile().getCollections()) { for (Collection collection : ServerLauncherController.getInstance().getCurrentProfile().getCollections()) {
this.targetServerCombo.addItem(collection.getName()); this.targetServerCombo.addItem(collection.getName());
} }
} }

View File

@ -2,7 +2,7 @@ package net.knarcraft.minecraftserverlauncher.userinterface;
import net.knarcraft.minecraftserverlauncher.Main; import net.knarcraft.minecraftserverlauncher.Main;
import net.knarcraft.minecraftserverlauncher.profile.Collection; import net.knarcraft.minecraftserverlauncher.profile.Collection;
import net.knarcraft.minecraftserverlauncher.profile.Controller; import net.knarcraft.minecraftserverlauncher.profile.ServerLauncherController;
import net.knarcraft.minecraftserverlauncher.server.Server; import net.knarcraft.minecraftserverlauncher.server.Server;
import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions; import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions;
@ -12,15 +12,16 @@ import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter; import java.io.File;
import java.awt.event.MouseEvent; import java.io.FileNotFoundException;
import java.awt.event.WindowAdapter; import java.io.FileWriter;
import java.awt.event.WindowEvent; import java.io.IOException;
import java.io.*; import java.io.PrintWriter;
import java.util.*; import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import static java.awt.Frame.NORMAL;
import static javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE; import static javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE;
import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.getResourceAsScanner; import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.getResourceAsScanner;
import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.getResourceAsStream; import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.getResourceAsStream;
@ -35,7 +36,7 @@ import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.getR
public class ServerLauncherGUI extends MessageHandler implements ActionListener, GUI { public class ServerLauncherGUI extends MessageHandler implements ActionListener, GUI {
private final JLabel lblStatuslabel = new JLabel("Servers are stopped"); private final JLabel lblStatuslabel = new JLabel("Servers are stopped");
private Controller controller; private final ServerLauncherController controller;
private Map<String, String> textStrings; private Map<String, String> textStrings;
private Tray applicationTray; private Tray applicationTray;
@ -64,6 +65,20 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener,
this.controller = Main.getController(); this.controller = Main.getController();
} }
/**
* Creates the application window
*
* @param silent <p>Whether to make the GUI silent (hidden, for testing)</p>
*/
public ServerLauncherGUI(boolean silent) throws IOException {
super(silent);
if (!silent) {
initialize(440, 170);
}
loadMessages();
this.controller = Main.getController();
}
/** /**
* Creates the application window with a preferred width and height * Creates the application window with a preferred width and height
* *
@ -146,7 +161,7 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener,
* Updates ServerLauncherGUI according to current profile settings * Updates ServerLauncherGUI according to current profile settings
*/ */
public void updateWithSavedProfileData() { public void updateWithSavedProfileData() {
Controller controller = Main.getController(); ServerLauncherController controller = Main.getController();
serversPane.removeAll(); serversPane.removeAll();
serverLauncherMenu.update(); serverLauncherMenu.update();
serverControlTab.update(); serverControlTab.update();
@ -311,7 +326,6 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener,
} }
/** /**
* Handles buttons and the combo on the main tab * Handles buttons and the combo on the main tab
* *

View File

@ -1,7 +1,7 @@
package net.knarcraft.minecraftserverlauncher.userinterface; package net.knarcraft.minecraftserverlauncher.userinterface;
import net.knarcraft.minecraftserverlauncher.profile.Controller;
import net.knarcraft.minecraftserverlauncher.profile.Profile; import net.knarcraft.minecraftserverlauncher.profile.Profile;
import net.knarcraft.minecraftserverlauncher.profile.ServerLauncherController;
import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions; import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions;
import javax.swing.*; import javax.swing.*;
@ -14,7 +14,7 @@ import java.util.Objects;
*/ */
public class ServerLauncherMenu implements ActionListener { public class ServerLauncherMenu implements ActionListener {
private JMenuBar menuBar; private final JMenuBar menuBar;
//Options //Options
private JCheckBoxMenuItem runInBackgroundCheckBoxMenuItem; private JCheckBoxMenuItem runInBackgroundCheckBoxMenuItem;
private JCheckBoxMenuItem delayStartupCheckBoxMenuItem; private JCheckBoxMenuItem delayStartupCheckBoxMenuItem;
@ -31,8 +31,8 @@ public class ServerLauncherMenu implements ActionListener {
private JMenuItem aboutMenuItem; private JMenuItem aboutMenuItem;
private JMenuItem storyMenuItem; private JMenuItem storyMenuItem;
private Controller controller; private final ServerLauncherController controller;
private ServerLauncherGUI serverLauncherGUI; private final ServerLauncherGUI serverLauncherGUI;
/** /**
* Initializes a new server launcher menu * Initializes a new server launcher menu
@ -41,7 +41,7 @@ public class ServerLauncherMenu implements ActionListener {
* @param serverLauncherGUI <p>The server launcher GUI to use</p> * @param serverLauncherGUI <p>The server launcher GUI to use</p>
*/ */
public ServerLauncherMenu(JMenuBar menuBar, ServerLauncherGUI serverLauncherGUI) { public ServerLauncherMenu(JMenuBar menuBar, ServerLauncherGUI serverLauncherGUI) {
this.controller = Controller.getInstance(); this.controller = ServerLauncherController.getInstance();
this.menuBar = menuBar; this.menuBar = menuBar;
this.serverLauncherGUI = serverLauncherGUI; this.serverLauncherGUI = serverLauncherGUI;
initialize(); initialize();

View File

@ -1,13 +1,17 @@
package net.knarcraft.minecraftserverlauncher.userinterface; package net.knarcraft.minecraftserverlauncher.userinterface;
import net.knarcraft.minecraftserverlauncher.Main; import net.knarcraft.minecraftserverlauncher.Main;
import net.knarcraft.minecraftserverlauncher.profile.Controller; import net.knarcraft.minecraftserverlauncher.profile.ServerLauncherController;
import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions; import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -20,9 +24,9 @@ public class Tray {
private SystemTray tray; private SystemTray tray;
private TrayIcon trayIcon; private TrayIcon trayIcon;
private Controller controller; private final ServerLauncherController controller;
private ServerLauncherGUI serverLauncherGUI; private final ServerLauncherGUI serverLauncherGUI;
private JFrame mainFrame; private final JFrame mainFrame;
/** /**
* Instantiates a new tray * Instantiates a new tray

View File

@ -12,7 +12,8 @@ public class WebBrowser {
private static JFrame browserFrame; private static JFrame browserFrame;
private static JTextPane editorPane; private static JTextPane editorPane;
private WebBrowser() {} private WebBrowser() {
}
/** /**
* Instantiates a new web browser * Instantiates a new web browser
@ -44,7 +45,8 @@ public class WebBrowser {
editorPane.setContentType("text/html"); editorPane.setContentType("text/html");
editorPane.addHyperlinkListener(hyperlinkEvent -> { editorPane.addHyperlinkListener(hyperlinkEvent -> {
if (hyperlinkEvent.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) { if (hyperlinkEvent.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) {
displayPage(hyperlinkEvent.getURL().toString()); } displayPage(hyperlinkEvent.getURL().toString());
}
}); });
} catch (IOException e) { } catch (IOException e) {
editorPane.setContentType("text/html"); editorPane.setContentType("text/html");

View File

@ -6,7 +6,17 @@ import net.knarcraft.minecraftserverlauncher.server.Server;
import net.knarcraft.minecraftserverlauncher.userinterface.GUI; import net.knarcraft.minecraftserverlauncher.userinterface.GUI;
import net.knarcraft.minecraftserverlauncher.userinterface.WebBrowser; import net.knarcraft.minecraftserverlauncher.userinterface.WebBrowser;
import java.io.*; import java.io.BufferedReader;
import java.io.BufferedWriter;
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.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
@ -107,6 +117,17 @@ public final class CommonFunctions {
return new Scanner(url.openStream()).useDelimiter("\\Z").next(); return new Scanner(url.openStream()).useDelimiter("\\Z").next();
} }
/**
* Gets a buffered reader for reading a given file
*
* @param path <p>The path of the file to read</p>
* @return <p>A buffered reader for reading the file</p>
* @throws FileNotFoundException <p>If the file does not exist</p>
*/
public static BufferedReader getFileReader(String path) throws FileNotFoundException {
return new BufferedReader(new InputStreamReader(new FileInputStream(path)));
}
/** /**
* Reads a file from disk * Reads a file from disk
* *
@ -115,7 +136,28 @@ public final class CommonFunctions {
* @throws IOException <p>If unable to find or read the file</p> * @throws IOException <p>If unable to find or read the file</p>
*/ */
public static String readFile(String path) throws IOException { public static String readFile(String path) throws IOException {
return CommonFunctions.readBufferedReader(new BufferedReader(new InputStreamReader(new FileInputStream(path)))); return CommonFunctions.readBufferedReader(getFileReader(path));
}
public static void writeFile(String path, String text) throws IOException {
writeFile(path, text, true);
}
/**
* Writes text to a file
*
* @param path <p>The path of the file to write to</p>
* @param text <p>The text to write</p>
* @param addTrailingNewline <p>Whether to add a new line at the end of the file</p>
* @throws IOException <p>If unable to write to the file</p>
*/
public static void writeFile(String path, String text, Boolean addTrailingNewline) throws IOException {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path)));
writer.write(text);
if (addTrailingNewline) {
writer.newLine();
}
writer.close();
} }
/** /**
@ -262,6 +304,7 @@ public final class CommonFunctions {
/** /**
* Removes all files within a folder * Removes all files within a folder
*
* @param target <p>The folder to delete from</p> * @param target <p>The folder to delete from</p>
*/ */
static void removeFilesRecursively(File target) { static void removeFilesRecursively(File target) {

View File

@ -1,6 +1,7 @@
package net.knarcraft.minecraftserverlauncher.utility; package net.knarcraft.minecraftserverlauncher.utility;
import net.knarcraft.minecraftserverlauncher.Main; import net.knarcraft.minecraftserverlauncher.Main;
import net.knarcraft.minecraftserverlauncher.profile.ServerLauncherController;
import net.knarcraft.minecraftserverlauncher.server.ServerVersionContainer; import net.knarcraft.minecraftserverlauncher.server.ServerVersionContainer;
import net.knarcraft.minecraftserverlauncher.userinterface.GUI; import net.knarcraft.minecraftserverlauncher.userinterface.GUI;
@ -21,9 +22,11 @@ public class JarBuilder {
private final String jarDirectory; private final String jarDirectory;
private final ServerVersionContainer versionContainer; private final ServerVersionContainer versionContainer;
private final GUI gui; private final GUI gui;
private final String javaCommand;
/** /**
* Instantiates a new jar builder * Instantiates a new jar builder
*
* @param buildDirectory <p>The directory containing BuildTool files</p> * @param buildDirectory <p>The directory containing BuildTool files</p>
* @param jarDirectory <p>The directory containing downloaded .jar files</p> * @param jarDirectory <p>The directory containing downloaded .jar files</p>
* @param gui <p>The GUI to write messages to</p> * @param gui <p>The GUI to write messages to</p>
@ -33,6 +36,7 @@ public class JarBuilder {
this.jarDirectory = jarDirectory; this.jarDirectory = jarDirectory;
this.gui = gui; this.gui = gui;
this.versionContainer = ServerVersionContainer.getInstance(); this.versionContainer = ServerVersionContainer.getInstance();
this.javaCommand = ServerLauncherController.getInstance().getJavaCommand();
} }
/** /**
@ -40,7 +44,7 @@ public class JarBuilder {
*/ */
public void buildSpigotJar() { public void buildSpigotJar() {
downloadBuildTools(); downloadBuildTools();
ProcessBuilder processBuilder = new ProcessBuilder("java", "-jar", "BuildTools.jar", "--rev", ProcessBuilder processBuilder = new ProcessBuilder(javaCommand, "-jar", "BuildTools.jar", "--rev",
"latest", "--output-dir", jarDirectory); "latest", "--output-dir", jarDirectory);
if (executeBuildProcess(processBuilder) && moveBuiltJar("spigot-", "SpigotLatest.jar")) { if (executeBuildProcess(processBuilder) && moveBuiltJar("spigot-", "SpigotLatest.jar")) {
gui.setStatus("Finished moving spigot.jar"); gui.setStatus("Finished moving spigot.jar");
@ -52,7 +56,7 @@ public class JarBuilder {
*/ */
public void buildBukkitJar() { public void buildBukkitJar() {
downloadBuildTools(); downloadBuildTools();
ProcessBuilder processBuilder = new ProcessBuilder("java", "-jar", "BuildTools.jar", "--compile", ProcessBuilder processBuilder = new ProcessBuilder(javaCommand, "-jar", "BuildTools.jar", "--compile",
"craftbukkit", "--rev", "latest", "--output-dir", jarDirectory); "craftbukkit", "--rev", "latest", "--output-dir", jarDirectory);
if (executeBuildProcess(processBuilder) && moveBuiltJar("craftbukkit-", "BukkitLatest.jar")) { if (executeBuildProcess(processBuilder) && moveBuiltJar("craftbukkit-", "BukkitLatest.jar")) {
gui.setStatus("Finished moving craftbukkit.jar"); gui.setStatus("Finished moving craftbukkit.jar");
@ -84,6 +88,7 @@ public class JarBuilder {
/** /**
* Moves a built .jar file to its target file * Moves a built .jar file to its target file
*
* @param searchString <p>The start of the name of the built file used to find it</p> * @param searchString <p>The start of the name of the built file used to find it</p>
* @param newName <p>The new name of the built file</p> * @param newName <p>The new name of the built file</p>
* @return <p>True if the .jar file was moved successfully</p> * @return <p>True if the .jar file was moved successfully</p>
@ -108,6 +113,7 @@ public class JarBuilder {
/** /**
* Starts the build process and initializes * Starts the build process and initializes
*
* @param processBuilder <p>The process builder to execute</p> * @param processBuilder <p>The process builder to execute</p>
* @return <p>True if the process exited successfully</p> * @return <p>True if the process exited successfully</p>
*/ */
@ -141,6 +147,7 @@ public class JarBuilder {
/** /**
* Gets the latest build tools version available * Gets the latest build tools version available
*
* @return <p>The latest build tools version available</p> * @return <p>The latest build tools version available</p>
* @throws IOException <p>If unable to read the version file</p> * @throws IOException <p>If unable to read the version file</p>
*/ */

View File

@ -5,9 +5,12 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import net.knarcraft.minecraftserverlauncher.Main; import net.knarcraft.minecraftserverlauncher.Main;
import net.knarcraft.minecraftserverlauncher.profile.ServerLauncherController;
import javax.swing.*; import javax.swing.*;
import java.io.*; import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Scanner; import java.util.Scanner;
@ -81,8 +84,9 @@ public final class Updater {
* @throws IOException <p>If unable to run the updater</p> * @throws IOException <p>If unable to run the updater</p>
*/ */
private static void runUpdater(String url) throws IOException { private static void runUpdater(String url) throws IOException {
String javaCommand = ServerLauncherController.getInstance().getJavaCommand();
ProcessBuilder builder; ProcessBuilder builder;
builder = new ProcessBuilder("java", "-jar", "Updater.jar", url, "yes", targetFile, "5", "nogui"); builder = new ProcessBuilder(javaCommand, "-jar", "Updater.jar", url, "yes", targetFile, "5", "nogui");
builder.directory(new File(Main.getApplicationWorkDirectory())); builder.directory(new File(Main.getApplicationWorkDirectory()));
builder.redirectErrorStream(true); builder.redirectErrorStream(true);
builder.start(); builder.start();

View File

@ -4,7 +4,6 @@ import net.knarcraft.minecraftserverlauncher.server.servertypes.ServerType;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
import java.util.Arrays; import java.util.Arrays;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;

View File

@ -5,7 +5,10 @@ import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.*; import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.createAllFolders; import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.createAllFolders;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
@ -35,14 +38,14 @@ public class ServerVersionContainerTest {
serverVersionContainer.reset(); serverVersionContainer.reset();
System.out.println(serverVersionContainer.toString()); System.out.println(serverVersionContainer.toString());
assertEquals("vanillaVersion;null\nsnapshotVersion;null\nbungeeVersion;null\nwaterfallVersions;\n" + assertEquals("vanillaVersion;null\nsnapshotVersion;null\nbungeeVersion;null\nwaterfallVersions;\n" +
"travertineVersions;\nspongeVanillaVersions;\nspongeForgeVersions;", "travertineVersions;\nspongeVanillaVersions;\nspongeForgeVersions;\ndownloadedBuildToolsVersion;null",
serverVersionContainer.toString()); serverVersionContainer.toString());
} }
@Test @Test
public void saveStateTest() throws IOException { public void saveStateTest() throws IOException {
serverVersionContainer.saveState(); serverVersionContainer.saveState();
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(versionFile))); BufferedReader reader = CommonFunctions.getFileReader(versionFile);
String savedData = CommonFunctions.readBufferedReader(reader); String savedData = CommonFunctions.readBufferedReader(reader);
reader.close(); reader.close();
assertEquals(serverVersionContainer.toString(), savedData); assertEquals(serverVersionContainer.toString(), savedData);

View File

@ -1,14 +1,17 @@
package net.knarcraft.minecraftserverlauncher.utility; package net.knarcraft.minecraftserverlauncher.utility;
import net.knarcraft.minecraftserverlauncher.Main; import net.knarcraft.minecraftserverlauncher.Main;
import net.knarcraft.minecraftserverlauncher.profile.ServerLauncherController;
import net.knarcraft.minecraftserverlauncher.userinterface.FakeGUI; import net.knarcraft.minecraftserverlauncher.userinterface.FakeGUI;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder; import org.junit.jupiter.api.TestMethodOrder;
import javax.naming.ConfigurationException;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -22,6 +25,15 @@ public class JarBuilderTest {
private static String targetDirectory; private static String targetDirectory;
private static String jarDirectory; private static String jarDirectory;
@BeforeAll
public static void preSetUp() {
try {
ServerLauncherController.getInstance().loadState(true);
} catch (ConfigurationException | IOException e) {
e.printStackTrace();
}
}
@BeforeEach @BeforeEach
public void setUp() { public void setUp() {
targetDirectory = Main.getApplicationWorkDirectory() + File.separator + "files" + File.separator + targetDirectory = Main.getApplicationWorkDirectory() + File.separator + "files" + File.separator +