diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java b/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java index 8b77908..fd8a6d3 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java @@ -1,10 +1,10 @@ package net.knarcraft.minecraftserverlauncher; import net.knarcraft.minecraftserverlauncher.profile.Collection; -import net.knarcraft.minecraftserverlauncher.profile.Profile; +import net.knarcraft.minecraftserverlauncher.profile.Controller; import net.knarcraft.minecraftserverlauncher.server.Server; -import net.knarcraft.minecraftserverlauncher.userinterface.GUI; import net.knarcraft.minecraftserverlauncher.userinterface.ServerConsoles; +import net.knarcraft.minecraftserverlauncher.userinterface.ServerLauncherGUI; import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions; import net.knarcraft.minecraftserverlauncher.utility.Updater; @@ -33,7 +33,8 @@ public class Main { private static boolean serversAreRunning = false; private static final String updateChannel = "alpha"; private static final String updateURL = "https://api.knarcraft.net/minecraftserverlauncher"; - private static GUI gui; + private static ServerLauncherGUI gui; + private static final Controller controller = Controller.getInstance(); public static void main(String[] args) throws IOException { Updater.checkForUpdate(updateURL, updateChannel, gui); @@ -45,8 +46,8 @@ public class Main { EventQueue.invokeLater(() -> { try { new ServerConsoles(); - Profile.load(); - gui = Profile.getGUI(); + controller.loadState(); + gui = controller.getGUI(); ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor(); exec.scheduleAtFixedRate(Main::updateConsoles, 10, 500, TimeUnit.MILLISECONDS); } catch (Exception e) { @@ -55,6 +56,15 @@ public class Main { }); } + /** + * Gets the controller used by the software + * + * @return

The controller used by the software

+ */ + public static Controller getController() { + return controller; + } + /** * Retrieves the directory the .jar file is running from * @@ -77,7 +87,7 @@ public class Main { */ private static void updateConsoles() { try { - for (Collection collection : Profile.getCurrent().getCollections()) { + for (Collection collection : controller.getCurrentProfile().getCollections()) { Server server = collection.getServer(); if (server.isEnabled() && server.getProcess() != null) { try { @@ -96,10 +106,10 @@ public class Main { } boolean runningNew = serversRunning(); if (!runningNew && serversAreRunning) { - Profile.getGUI().updateRunning(false); - Profile.getGUI().setStatus("Servers are stopped"); + gui.updateRunning(false); + gui.setStatus("Servers are stopped"); } else if (runningNew && !serversAreRunning) { - Profile.getGUI().updateRunning(true); + gui.updateRunning(true); } serversAreRunning = runningNew; } catch (Exception e) { @@ -114,7 +124,7 @@ public class Main { */ private static boolean serversRunning() { int num = 0; - for (Collection collection : Profile.getCurrent().getCollections()) { + for (Collection collection : controller.getCurrentProfile().getCollections()) { if (collection.getServer().isStarted() || (collection.getServer().getProcess() != null && collection.getServer().getProcess().isAlive())) { num++; diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Collection.java b/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Collection.java index 42b3334..0dd037e 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Collection.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Collection.java @@ -6,7 +6,6 @@ import net.knarcraft.minecraftserverlauncher.userinterface.ServerConsoles; import net.knarcraft.minecraftserverlauncher.userinterface.ServerTab; import javax.naming.ConfigurationException; -import java.io.Serializable; /** * Acts as a wrapper for objects necessary for each server. @@ -15,9 +14,9 @@ import java.io.Serializable; * @version 1.0.0 * @since 1.0.0 */ -public class Collection implements Serializable { +public class Collection { private final Server server; - private final transient ServerTab serverTab; + private final ServerTab serverTab; private final Console serverConsole; private final String name; @@ -45,25 +44,8 @@ public class Collection implements Serializable { this.server = server; this.serverConsole = ServerConsoles.addConsoleTab(serverName); this.name = serverName; - } - - /** - * Creates a new collection with the given parameters - * - * @param name

The name identifying the server, server tab, collection and server console

- * @param serverPath

The path of the server folder

- * @param enabled

Whether the server should be run when starting servers

- * @param typeName

The name of the server type the server uses

- * @param serverVersion

The version of the running server type.

- * @param maxRam

The maximum amount of RAM the server is allowed to use.

- */ - Collection(String name, String serverPath, boolean enabled, String typeName, String serverVersion, String maxRam) - throws ConfigurationException { - this.serverTab = new ServerTab(name); - this.server = new Server(name, serverPath, enabled, typeName, serverVersion, maxRam); - this.serverConsole = ServerConsoles.addConsoleTab(name); - this.name = name; - this.serverTab.setData(serverPath, enabled, typeName, serverVersion, maxRam); + this.serverTab.setData(server.getPath(), server.isEnabled(), server.getTypeName(), server.getServerVersion(), + server.getMaxRam()); } /** diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Controller.java b/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Controller.java new file mode 100644 index 0000000..49b86b6 --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Controller.java @@ -0,0 +1,293 @@ +package net.knarcraft.minecraftserverlauncher.profile; + +import net.knarcraft.minecraftserverlauncher.Main; +import net.knarcraft.minecraftserverlauncher.server.Server; +import net.knarcraft.minecraftserverlauncher.server.ServerTypeHandler; +import net.knarcraft.minecraftserverlauncher.userinterface.ServerLauncherGUI; +import net.knarcraft.minecraftserverlauncher.userinterface.ServerTab; +import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions; +import net.knarcraft.minecraftserverlauncher.utility.JarDownloader; + +import javax.naming.ConfigurationException; +import java.io.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; +import java.util.concurrent.Executors; + +/** + * This class controls + */ +public class Controller { + + private final String workingDirectory = Main.getApplicationWorkDirectory() + File.separator + "files"; + private final String profilesFile = workingDirectory + File.separator + "Profiles.txt"; + private final String mainFile = workingDirectory + File.separator + "Config.txt"; + private final String jarDirectory = workingDirectory + File.separator + "Jars" + File.separator; + private final List profileList; + private ServerLauncherGUI serverLauncherGUI; + private Profile currentProfile; + private boolean downloadAllJars; + private static Controller controller; + + private Controller() { + this.profileList = new ArrayList<>(); + } + + /** + * Gets an instance of the controller + * + * @return

An instance of the controller

+ */ + public static Controller getInstance() { + if (controller == null) { + controller = new Controller(); + } + return controller; + } + + /** + * Returns the GUI used by the software + * + * @return

The GUI used by the software

+ */ + public ServerLauncherGUI getGUI() { + return this.serverLauncherGUI; + } + + /** + * Gets whether to download all jar files + * + * @return

Whether to download all .jar files

+ */ + public boolean getDownloadAllJars() { + return downloadAllJars; + } + + /** + * Gets whether to run in background after closing + * + * @return

Whether to run in background after closing

+ */ + public boolean getRunInBackground() { + return currentProfile.getRunInBackground(); + } + + /** + * Gets whether to delay server startup + * + * @return

Whether to delay server startup

+ */ + public int getDelayStartup() { + return currentProfile.getDelayStartup(); + } + + @Override + public String toString() { + int guiWidth; + int guiHeight; + if (serverLauncherGUI == null) { + guiWidth = 440; + guiHeight = 170; + } else { + guiWidth = serverLauncherGUI.getSize().width; + guiHeight = serverLauncherGUI.getSize().height; + } + return String.format("%s;%d;%d;%b", currentProfile.getName(), guiWidth, guiHeight, downloadAllJars); + } + + /** + * Gets a profile by its name + * + * @param name

The name of the profile to get

+ * @return

The profile with the given name or null if not found

+ */ + public Profile getProfileByName(String name) { + for (Profile profile : profileList) { + if (profile.getName().equals(name)) { + return profile; + } + } + return null; + } + + /** + * Gets the names of all available profiles + * + * @return

A list of all available profiles

+ */ + public List getProfileNames() { + List profileNames = new ArrayList<>(); + profileList.forEach((profile) -> profileNames.add(profile.getName())); + return profileNames; + } + + /** + * Adds a profile if the name is valid and unique. + * + * @param name The name of the new profile. + */ + public void addProfile(String name) { + if (!CommonFunctions.nameIsValid(name)) { + serverLauncherGUI.showError("Profile name cannot be blank and cannot contain special characters."); + return; + } + for (Profile profile : profileList) { + if (profile.getName().equals(name)) { + serverLauncherGUI.showError("There is already a profile with this name."); + return; + } + } + Profile newProfile = new Profile(name); + profileList.add(newProfile); + if (currentProfile == null) { + currentProfile = newProfile; + } + } + + /** + * Removes a profile with the given name from the list of profiles, if such a profile exists + * + * @param name

The name of the profile to rempve

+ */ + public void removeProfile(String name) { + if (profileList.size() > 1) { + profileList.removeIf(profile -> profile.getName().equals(name)); + } else { + serverLauncherGUI.showError("This software requires the existence of at least one profile."); + } + } + + /** + * Gets the currently selected profile + * + * @return

The currently selected profile

+ */ + public Profile getCurrentProfile() { + return this.currentProfile; + } + + /** + * Loads data about the controller from a save string + * + * @param data

The save string to load

+ * @return

The currently selected profile

+ * @throws IOException

If unable to create the GUI

+ */ + private String fromString(String data) throws IOException { + String[] dataList = data.split(";"); + this.downloadAllJars = Boolean.parseBoolean(dataList[3]); + this.serverLauncherGUI = new ServerLauncherGUI(Integer.parseInt(dataList[1]), Integer.parseInt(dataList[2])); + return dataList[0]; + } + + /** + * Reads profiles and servers from a text file. + */ + public void loadState() throws ConfigurationException, IOException { + //Loads data regarding this controller + String currentProfile = null; + if (new File(mainFile).exists()) { + String controllerData = CommonFunctions.readBufferedReader(new BufferedReader(new InputStreamReader(new FileInputStream(mainFile)))); + currentProfile = this.fromString(controllerData); + } else { + this.serverLauncherGUI = new ServerLauncherGUI(); + } + + try (Scanner in = new Scanner(new File(profilesFile))) { + while (in.hasNextLine()) { + String profileData = in.nextLine(); + Profile loadedProfile = Profile.fromString(profileData); + profileList.add(loadedProfile); + } + } catch (FileNotFoundException e) { + addProfile("Default"); + } + + this.currentProfile = getProfileByName(currentProfile); + if (this.currentProfile == null) { + this.currentProfile = this.profileList.get(0); + } + + this.serverLauncherGUI.updateProfiles(); + this.serverLauncherGUI.update(); + this.currentProfile.updateConsoles(); + if (this.downloadAllJars) { + Executors.newSingleThreadExecutor().execute(() -> { + JarDownloader downloader = new JarDownloader(serverLauncherGUI, jarDirectory); + try { + downloader.downloadJars(); + } catch (IOException e) { + e.printStackTrace(); + } + }); + } + if (this.currentProfile.getRunInBackground()) { + Executors.newSingleThreadExecutor().execute(Server::startServers); + this.serverLauncherGUI.hide(); + } + } + + /** + * Sets the download all jars option + * + * @param downloadAllJars

Whether to download all jars

+ */ + public void setDownloadAllJars(boolean downloadAllJars) { + this.downloadAllJars = downloadAllJars; + } + + /** + * Sets the currently selected profile + * + * @param profileName

The name of the currently selected profile

+ */ + 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.toString()); + 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 + */ + private void saveGUIStateToServer() { + for (Collection collection : this.currentProfile.getCollections()) { + Server server = collection.getServer(); + ServerTab serverTab = collection.getServerTab(); + server.setPath(serverTab.getPath()); + server.setMaxRam(serverTab.getMaxRam()); + try { + server.setType(ServerTypeHandler.getByName(serverTab.getType())); + } catch (ConfigurationException e) { + e.printStackTrace(); + } + try { + server.setServerVersion(serverTab.getVersion()); + } catch (IllegalArgumentException e) { + serverLauncherGUI.showError("Invalid server version for " + server.getName()); + } + server.setEnabled(serverTab.enabled()); + } + } + +} diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Profile.java b/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Profile.java index c1b51a5..d23fb0a 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Profile.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Profile.java @@ -2,23 +2,14 @@ package net.knarcraft.minecraftserverlauncher.profile; import net.knarcraft.minecraftserverlauncher.Main; import net.knarcraft.minecraftserverlauncher.server.Server; -import net.knarcraft.minecraftserverlauncher.server.ServerTypeHandler; import net.knarcraft.minecraftserverlauncher.userinterface.ServerConsoles; import net.knarcraft.minecraftserverlauncher.userinterface.ServerLauncherGUI; -import net.knarcraft.minecraftserverlauncher.userinterface.ServerTab; -import net.knarcraft.minecraftserverlauncher.utility.JarDownloader; +import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions; import javax.naming.ConfigurationException; import javax.swing.*; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; +import java.io.*; import java.util.ArrayList; -import java.util.NoSuchElementException; -import java.util.Scanner; -import java.util.concurrent.Executors; /** * Contains all user settings, and a list of servers. @@ -27,110 +18,38 @@ import java.util.concurrent.Executors; * @version 1.0.0 * @since 1.0.0 */ -public class Profile implements java.io.Serializable { - private static final ArrayList profiles = new ArrayList<>(); - private static final String workingDirectory = Main.getApplicationWorkDirectory() + File.separator + "files"; - private static final String profilesDir = workingDirectory; - private static final String profilesFile = workingDirectory + File.separator + "Profiles.txt"; - private static final String jarDirectory = workingDirectory + File.separator + "Jars" + File.separator; - private static Profile current; - private static transient ServerLauncherGUI serverLauncherGui; +public class Profile { + + private static final ServerLauncherGUI serverLauncherGui = Main.getController().getGUI(); private final ArrayList collections; private final String name; private boolean runInBackground; private int delayStartup; - private boolean downloadAllAvailableJARFiles; - private Profile(String name) { + /** + * Instantiates a new default profile + * + * @param name

The name of the profile

+ */ + public Profile(String name) { this.collections = new ArrayList<>(); this.name = name; this.runInBackground = false; this.delayStartup = 0; - this.downloadAllAvailableJARFiles = false; - profiles.add(this); - if (current == null) { - current = this; - } } - private Profile(String name, boolean runInBackground, int delayStartup, boolean downloadAllAvailableJARFiles) { + /** + * Instantiates a new profile + * + * @param name

The name of the profile

+ * @param runInBackground

Whether to run the software in the background the next time it starts

+ * @param delayStartup

Whether to delay the startup of servers

+ */ + private Profile(String name, boolean runInBackground, int delayStartup) { this.collections = new ArrayList<>(); this.name = name; this.runInBackground = runInBackground; this.delayStartup = delayStartup; - this.downloadAllAvailableJARFiles = downloadAllAvailableJARFiles; - profiles.add(this); - if (current == null) { - current = this; - } - } - - public static ServerLauncherGUI getGUI() { - return serverLauncherGui; - } - - public static Profile getCurrent() { - return current; - } - - /** - * Set the current profile to the profile with a certain name. - * - * @param name The name of the profile - */ - public static void setCurrent(String name) { - for (Profile profile : profiles) { - if (profile.name.equals(name)) { - current = profile; - break; - } - } - } - - public static Profile getProfile(String name) { - for (Profile profile : profiles) { - if (profile.name.equals(name)) { - return profile; - } - } - return null; - } - - public static ArrayList getProfiles() { - return profiles; - } - - /** - * Adds a profile if the name is valid and unique. - * - * @param name The name of the new profile. - */ - public static void addProfile(String name) { - if (name == null) { //If a user cancels or crosses out window - return; - } - if (name.equals("") && !name.matches("^[!?;]+$")) { - serverLauncherGui.showError("Profile name can't be blank."); - return; - } - for (Profile profile : profiles) { - if (profile.name.equals(name)) { - serverLauncherGui.showError("There is already a profile with this name."); - return; - } - } - new Profile(name); - } - - /** - * Removes a profile with the given name from the list of profiles, if such a profile exists - * - * @param name

The name of the profile to rempve

- */ - public static void removeProfile(String name) { - if (profiles.size() > 1) { - profiles.removeIf(profile -> profile.name.equals(name)); - } } /** @@ -140,67 +59,47 @@ public class Profile implements java.io.Serializable { * @return

The new profile

*/ private static Profile parseProfile(String[] profileData) { - return new Profile( - profileData[0], - Boolean.parseBoolean(profileData[1]), - Integer.parseInt(profileData[2]), - Boolean.parseBoolean(profileData[3]) - ); + return new Profile(profileData[0], Boolean.parseBoolean(profileData[1]), Integer.parseInt(profileData[2])); } /** - * Parses a server, and creates a new collection. + * Gets whether the software should keep running in the background * - * @param profile

The profile which to add the collection

- * @param serverData

The data to parse

+ * @return

Whether the software should keep running in the backgound

*/ - private static void parseServer(Profile profile, String[] serverData) throws ConfigurationException { - profile.collections.add(new Collection( - serverData[0], - serverData[1], - Boolean.parseBoolean(serverData[2]), - serverData[3], - serverData[4], - serverData[5]) - ); - } - public boolean getRunInBackground() { return this.runInBackground; } + /** + * Sets whether the software should keep running in the background + * + * @param value

Whether the software should keep running in the background

+ */ public void setRunInBackground(boolean value) { this.runInBackground = value; } + /** + * Gets the number of seconds to delay startup + * + * @return

The number of seconds to delay starup

+ */ public int getDelayStartup() { return this.delayStartup; } + /** + * Sets the amount of time to delay startup + * + * @param value

The number of seconds to delay startup

+ */ public void setDelayStartup(int value) { if (value >= 0) { this.delayStartup = value; } } - /** - * Gets the state of the download all jar files setting - * - * @return

Whether to download all jars

- */ - public boolean getDownloadAllAvailableJARFiles() { - return this.downloadAllAvailableJARFiles; - } - - /** - * Sets the state of the download all jar files setting - * - * @param value

The new value of the download all jar files setting

- */ - public void setDownloadAllAvailableJARFiles(boolean value) { - this.downloadAllAvailableJARFiles = value; - } - /** * Gets all collections stored as part of this profile * @@ -243,13 +142,7 @@ public class Profile implements java.io.Serializable { if (name == null) { //If a user cancels or crosses out window return; } - if (getCollection(name) == null && - !name.equals("") && - !name.equals("All") && - !name.contains("!") && - !name.contains("?") && - !name.contains(";") - ) { + if (getCollection(name) == null && !name.equals("All") && CommonFunctions.nameIsValid(name)) { collections.add(new Collection(name)); } else { serverLauncherGui.showError("A server name must my unique and not empty or \"All\"." + @@ -257,6 +150,11 @@ public class Profile implements java.io.Serializable { } } + /** + * Removes the collection with the given name + * + * @param name

The name of the collection to remove

+ */ public void removeCollection(String name) { for (int i = 0; i < collections.size(); i++) { if (collections.get(i).getName().equals(name)) { @@ -267,6 +165,9 @@ public class Profile implements java.io.Serializable { } } + /** + * Updates console tabs with the current servers + */ public void updateConsoles() { JTabbedPane consolesTab = ServerConsoles.getTabbedPane(); consolesTab.removeAll(); @@ -278,8 +179,8 @@ public class Profile implements java.io.Serializable { /** * Sends a command to a server, or all servers * - * @param serverName The target server - * @param command The command to send. + * @param serverName

The target server

+ * @param command

The command to send

*/ public void sendCommand(String serverName, String command) { if (serverName.equals("All")) { @@ -305,194 +206,45 @@ public class Profile implements java.io.Serializable { } } - /** - * Reads all server tabs, and saves it to the variables of the corresponding servers. - * Saves all profiles and servers to a text file. - */ - public void save() throws FileNotFoundException { - /*try { - FileOutputStream fileOut = - new FileOutputStream(profilesFile); - ObjectOutputStream out = new ObjectOutputStream(fileOut); - out.writeObject(this); - out.close(); - fileOut.close(); - } catch (IOException i) { - System.out.println("Unable to serialize or write the profile settings file"); - i.printStackTrace(); - }*/ - + @Override + public String toString() { + StringBuilder saveString = new StringBuilder(String.format( + "%s;%b;%d?", + this.name, + this.runInBackground, + this.delayStartup) + ); for (Collection collection : this.collections) { - Server server = collection.getServer(); - ServerTab serverTab = collection.getServerTab(); - server.setPath(serverTab.getPath()); - server.setMaxRam(serverTab.getMaxRam()); - try { - server.setType(ServerTypeHandler.getByName(serverTab.getType())); - } catch (ConfigurationException e) { - e.printStackTrace(); - } - try { - server.setServerVersion(serverTab.getVersion()); - } catch (IllegalArgumentException e) { - serverLauncherGui.showError("Invalid server version for " + server.getName()); - } - server.setEnabled(serverTab.enabled()); - } - if (!new File(profilesDir).exists() && !new File(profilesDir).mkdirs()) { - serverLauncherGui.showError("Unable to create the folder " + profilesDir); - throw new FileNotFoundException("Unable to create the profiles folder: " + profilesDir); - } - try (PrintWriter file = new PrintWriter(profilesFile)) { - int width; - int height; - if (serverLauncherGui == null) { - width = 440; - height = 170; - } else { - width = serverLauncherGui.getSize().width; - height = serverLauncherGui.getSize().height; - } - file.println(String.format( - "%s;%s;%s", - current.name, - width, - height - )); - file.close(); - for (Profile profile : profiles) { - StringBuilder saveString = new StringBuilder(String.format( - "%s;%b;%d;%b?", - profile.name, - profile.runInBackground, - profile.delayStartup, - profile.downloadAllAvailableJARFiles) - ); - for (Collection collection : profile.collections) { - Server server = collection.getServer(); - saveString.append(String.format( - "%s;%s;%b;%s;%s;%s!", - server.getName(), - server.getPath(), - server.isEnabled(), - server.getTypeName(), - server.getServerVersion(), - server.getMaxRam() - ) - ); - } - saveString = new StringBuilder(saveString.substring(0, saveString.length() - 1)); - try (PrintWriter fileAppend = new PrintWriter(new FileWriter( - profilesFile, - true - ))) { - fileAppend.println(saveString); - } catch (IOException e) { - if (serverLauncherGui != null) { - serverLauncherGui.showError("Unable to save to file. Try running the software as an administrator."); - } else { - System.out.println("Unable to save to file. Try running the software as an administrator."); - } - throw new FileNotFoundException("Unable to save to the profiles file."); - } - } - } catch (IOException e) { - if (serverLauncherGui != null) { - serverLauncherGui.showError("Unable to save to file. Try running the software as an administrator."); - } - throw new FileNotFoundException("Unable to create the profiles file"); + saveString.append(collection.getServer().toString()); } + saveString = new StringBuilder(saveString.substring(0, saveString.length() - 1)); + return saveString.toString(); } /** - * Reads profiles and servers from a text file. + * Gets a profile given a saved string + * + * @param profileString

The string containing all profile data

+ * @return

A profile with the given data

+ * @throws ConfigurationException

If unable to load one of the profile's servers

*/ - public static void load() throws ConfigurationException, IOException { - /*Profile p; - if (!new File(profilesFile).exists()) { - addProfile("Default"); - return; - } - try { - FileInputStream fileIn = new FileInputStream(profilesFile); - ObjectInputStream in = new ObjectInputStream(fileIn); - p = (Profile) in.readObject(); - in.close(); - fileIn.close(); - profiles.add(p); - } catch (IOException i) { - i.printStackTrace(); - } catch (ClassNotFoundException c) { - System.out.println("Profile class not found"); - c.printStackTrace(); - }*/ - - try (Scanner in = new Scanner(new File(profilesFile))) { - try { - String[] staticData = in.nextLine().split(";", -1); - String profileName = staticData[0]; - int guiWidth = Integer.parseInt(staticData[1]); - int guiHeight = Integer.parseInt(staticData[2]); - serverLauncherGui = new ServerLauncherGUI(guiWidth, guiHeight); - while (in.hasNextLine()) { - String line = in.nextLine(); - if (line.contains("?")) { - String[] data = line.split("\\?"); - String[] profileData = data[0].split(";", -1); - Profile profile = parseProfile(profileData); - if (data[1].contains("!")) { - String[] servers = data[1].split("!", -1); - for (String server : servers) { - String[] serverData = server.split(";", -1); - parseServer(profile, serverData); - } - } else { - String[] serverData = data[1].split(";", -1); - parseServer(profile, serverData); - } - } else { - String[] profileData = line.split(";", -1); - parseProfile(profileData); - } + public static Profile fromString(String profileString) throws ConfigurationException { + Profile profile; + if (profileString.contains("?")) { + String[] data = profileString.split("\\?"); + String[] profileData = data[0].split(";", -1); + profile = parseProfile(profileData); + if (data[1].contains("!")) { + String[] servers = data[1].split("!", -1); + for (String server : servers) { + profile.collections.add(new Collection(Server.fromString(server))); } - current = getProfile(profileName); - } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) { - e.printStackTrace(); - serverLauncherGui = new ServerLauncherGUI(); - serverLauncherGui.showError("Invalid Profile.txt file. Profiles could not be loaded. If this error persists, please " + - "manually delete the file."); - System.exit(1); - } catch (IOException e) { - e.printStackTrace(); + } else { + profile.collections.add(new Collection(Server.fromString(data[1]))); } - if (profiles.size() == 0) { - addProfile("Default"); - } - } catch (FileNotFoundException | NoSuchElementException e) { - try { - serverLauncherGui = new ServerLauncherGUI(); - serverLauncherGui.showMessage("A profiles file was not found. Default profile was created."); - } catch (IOException ex) { - ex.printStackTrace(); - } - addProfile("Default"); - } - serverLauncherGui.update(); - serverLauncherGui.updateProfiles(); - current.updateConsoles(); - if (current.downloadAllAvailableJARFiles) { - Executors.newSingleThreadExecutor().execute(() -> { - JarDownloader downloader = new JarDownloader(serverLauncherGui, jarDirectory); - try { - downloader.downloadJars(); - } catch (IOException e) { - e.printStackTrace(); - } - }); - } - if (current.runInBackground) { - Executors.newSingleThreadExecutor().execute(Server::startServers); - serverLauncherGui.hide(); + } else { + profile = parseProfile(profileString.split(";", -1)); } + return profile; } } diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java index 2a237d5..40dc806 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java @@ -2,7 +2,7 @@ package net.knarcraft.minecraftserverlauncher.server; import net.knarcraft.minecraftserverlauncher.Main; import net.knarcraft.minecraftserverlauncher.profile.Collection; -import net.knarcraft.minecraftserverlauncher.profile.Profile; +import net.knarcraft.minecraftserverlauncher.profile.Controller; import net.knarcraft.minecraftserverlauncher.server.servertypes.ServerType; import javax.naming.ConfigurationException; @@ -25,7 +25,7 @@ import java.util.concurrent.TimeUnit; * @version 1.0.0 * @since 1.0.0 */ -public class Server implements java.io.Serializable { +public class Server { /** * Available ram sizes. For ServerLauncherGUI dropdown */ @@ -108,7 +108,7 @@ public class Server implements java.io.Serializable { * @throws IOException If a writer's process is already closed but not null. */ public static void stop() throws IOException { - for (Collection collection : Profile.getCurrent().getCollections()) { + for (Collection collection : Main.getController().getCurrentProfile().getCollections()) { Server server = collection.getServer(); if (server.writer != null) { if (server.type.isProxy()) { @@ -127,16 +127,17 @@ public class Server implements java.io.Serializable { * Runs all enabled servers with their settings */ public static void startServers() { - Profile.getGUI().setStatus("Starting servers"); - for (Collection collection : Profile.getCurrent().getCollections()) { + Controller controller = Main.getController(); + controller.getGUI().setStatus("Starting servers"); + for (Collection collection : controller.getCurrentProfile().getCollections()) { if (!collection.getServer().runServer()) { - Profile.getGUI().setStatus("An error occurred. Start aborted"); + controller.getGUI().setStatus("An error occurred. Start aborted"); try { Server.stop(); } catch (IOException e) { e.printStackTrace(); } - Profile.getGUI().updateRunning(false); + controller.getGUI().updateRunning(false); return; } } @@ -322,7 +323,7 @@ public class Server implements java.io.Serializable { */ public void addPlayer(String name) { this.playerList.add(name); - Profile.getGUI().addPlayer(name); + Main.getController().getGUI().addPlayer(name); } /** @@ -332,7 +333,7 @@ public class Server implements java.io.Serializable { */ public void removePlayer(String name) { playerList.removeIf(player -> player.equals(name)); - Profile.getGUI().removePlayer(name); + Main.getController().getGUI().removePlayer(name); } /** @@ -350,22 +351,24 @@ public class Server implements java.io.Serializable { * @return

True if nothing went wrong

*/ private boolean runServer() { + //Ignore a disabled server if (!this.enabled) { this.started = false; return true; } - this.started = true; + //Tries to do necessary pre-start work if (!initializeJarDownload() || !delayStartup()) { + this.started = false; return false; } - + //Starts the server if possible try { startServerProcess(); - Profile.getGUI().setStatus("Servers are running"); + Main.getController().getGUI().setStatus("Servers are running"); this.started = true; return true; } catch (IOException e) { - Profile.getGUI().setStatus("Could not start server"); + Main.getController().getGUI().setStatus("Could not start server"); this.started = false; return false; } @@ -379,16 +382,11 @@ public class Server implements java.io.Serializable { private void startServerProcess() throws IOException { ProcessBuilder builder; String serverPath; - String serverFile; + //Decide the path of the .jar file to be executed if (type.getName().equals("Custom")) { - serverFile = serverVersion; + serverPath = this.path + File.separator + serverVersion; } else { - serverFile = this.type.getName() + serverVersion + ".jar"; - } - if (!type.getName().equals("Custom")) { - serverPath = jarDirectory + serverFile; - } else { - serverPath = this.path + File.separator + serverFile; + serverPath = jarDirectory + this.type.getName() + serverVersion + ".jar"; } builder = new ProcessBuilder("java", "-Xmx" + this.maxRam, "-Xms512M", "-Djline.terminal=jline.UnsupportedTerminal", "-Dcom.mojang.eula.agree=true", "-jar", serverPath, @@ -407,8 +405,8 @@ public class Server implements java.io.Serializable { */ private boolean delayStartup() { try { - Profile.getGUI().setStatus("Delaying startup"); - TimeUnit.SECONDS.sleep(Profile.getCurrent().getDelayStartup()); + Main.getController().getGUI().setStatus("Delaying startup"); + TimeUnit.SECONDS.sleep(Main.getController().getCurrentProfile().getDelayStartup()); return true; } catch (InterruptedException e) { e.printStackTrace(); @@ -423,13 +421,14 @@ public class Server implements java.io.Serializable { * @return

True if nothing went wrong

*/ private boolean initializeJarDownload() { - if (!Profile.getCurrent().getDownloadAllAvailableJARFiles()) { + Controller controller = Main.getController(); + if (!controller.getDownloadAllJars()) { try { - Profile.getGUI().setStatus("Downloading jar..."); + controller.getGUI().setStatus("Downloading jar..."); this.downloadJar(); - Profile.getGUI().setStatus("File downloaded"); + controller.getGUI().setStatus("File downloaded"); } catch (IOException e) { - Profile.getGUI().setStatus("Error: Jar file not found"); + controller.getGUI().setStatus("Error: Jar file not found"); e.printStackTrace(); this.started = false; return false; diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/ServerVersionContainer.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/ServerVersionContainer.java index a95680a..dc43ec2 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/server/ServerVersionContainer.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/ServerVersionContainer.java @@ -10,10 +10,10 @@ import java.util.Map; /** * This class acts as a container for all "latest" server versions */ -public class ServerVersionContainer implements java.io.Serializable { +public class ServerVersionContainer { private static ServerVersionContainer serverVersionContainer; - private String versionFile = Main.getApplicationWorkDirectory() + File.separator + "files" + File.separator + "versions.csv"; + private final String versionFile = Main.getApplicationWorkDirectory() + File.separator + "files" + File.separator + "versions.csv"; private String vanillaVersion; private String snapshotVersion; private String bungeeVersion; @@ -273,15 +273,6 @@ public class ServerVersionContainer implements java.io.Serializable { saveState(); } - /** - * Gets the entire sponge vanilla version map - * - * @return

The entire sponge vanilla version map

- */ - public Map getSpongeVanillaVersions() { - return this.spongeVanillaVersions; - } - /** * Gets a specific sponge vanilla version * @@ -292,16 +283,6 @@ public class ServerVersionContainer implements java.io.Serializable { return spongeVanillaVersions.get(versionKey); } - /** - * Replaces the entire sponge vanilla version map - * - * @param newVersions

The new version map to use

- */ - public void setSpongeVanillaVersion(Map newVersions) { - this.spongeVanillaVersions = newVersions; - saveState(); - } - /** * Sets the current version for a given sponge vanilla version * diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/BungeeCord.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/BungeeCord.java index 0f2e93e..a0b946b 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/BungeeCord.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/BungeeCord.java @@ -12,9 +12,9 @@ import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.stri public class BungeeCord extends AbstractServerType { - private String versionURL; - private String srcStart; - private String srcEnd; + private final String versionURL; + private final String srcStart; + private final String srcEnd; /** * Instantiates a new BungeeCord server type diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/CraftBukkit.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/CraftBukkit.java index a56e389..235d2ef 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/CraftBukkit.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/CraftBukkit.java @@ -10,7 +10,7 @@ import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.down */ public class CraftBukkit extends AbstractServerType { - private String downloadURLPart; + private final String downloadURLPart; /** * Instantiates a new server type diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Custom.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Custom.java index 224408c..814b7a9 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Custom.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Custom.java @@ -1,7 +1,6 @@ package net.knarcraft.minecraftserverlauncher.server.servertypes; import java.io.File; -import java.io.IOException; public class Custom extends AbstractServerType { /** @@ -14,7 +13,7 @@ public class Custom extends AbstractServerType { } @Override - public boolean downloadJar(String folder, String version) throws IOException { + public boolean downloadJar(String folder, String version) { File filePath = new File(folder + version); return filePath.isFile(); } diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/SpongeVanilla.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/SpongeVanilla.java index 3fa326f..ed18c15 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/SpongeVanilla.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/SpongeVanilla.java @@ -11,10 +11,10 @@ import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.down public class SpongeVanilla extends AbstractServerType { - private String versionURL; - private String srcStart; - private String srcEnd; - private String downloadURLPart; + private final String versionURL; + private final String srcStart; + private final String srcEnd; + private final String downloadURLPart; /** * Instantiates a new SpongeVanilla server type diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Travertine.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Travertine.java index 8286d6f..bebad43 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Travertine.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Travertine.java @@ -19,7 +19,7 @@ public class Travertine extends Waterfall { String srcEnd, String downloadURL) { super(typeName, isProxy, versions, versionURL, srcStart, srcEnd, downloadURL); this.oldVersion = ServerVersionContainer.getInstance().getTravertineVersion(); - this.versionUpdateFunction = (newVersion) -> serverVersionContainer.setTravertineVersion(newVersion); + this.versionUpdateFunction = serverVersionContainer::setTravertineVersion; } } diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Waterfall.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Waterfall.java index cea6ce0..3b8d247 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Waterfall.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/servertypes/Waterfall.java @@ -6,7 +6,6 @@ import java.io.File; import java.io.IOException; import java.nio.file.Paths; import java.util.function.Consumer; -import java.util.function.Function; import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.downloadFile; import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.readFile; @@ -14,12 +13,12 @@ import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.stri public class Waterfall extends AbstractServerType { - private String srcStart; - private String srcEnd; - private String versionURL; + private final String srcStart; + private final String srcEnd; + private final String versionURL; String oldVersion; Consumer versionUpdateFunction; - ServerVersionContainer serverVersionContainer; + final ServerVersionContainer serverVersionContainer; /** * Instantiates a new Waterfall server type @@ -40,7 +39,7 @@ public class Waterfall extends AbstractServerType { this.srcEnd = srcEnd; this.versionURL = versionURL; this.oldVersion = serverVersionContainer.getWaterfallVersion(); - this.versionUpdateFunction = (newVersion) -> serverVersionContainer.setWaterfallVersion(newVersion); + this.versionUpdateFunction = serverVersionContainer::setWaterfallVersion; } @Override diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/Console.java b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/Console.java index 2601f4f..a420e03 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/Console.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/Console.java @@ -1,6 +1,6 @@ package net.knarcraft.minecraftserverlauncher.userinterface; -import net.knarcraft.minecraftserverlauncher.profile.Profile; +import net.knarcraft.minecraftserverlauncher.Main; import javax.swing.*; import javax.swing.text.DefaultCaret; @@ -66,7 +66,7 @@ public class Console implements ActionListener, KeyListener { //Sends the command from the input to the server with the same name. if (e.getSource() == textInput) { java.lang.String text = textInput.getText(); - Profile.getCurrent().sendCommand(this.name, text); + Main.getController().getCurrentProfile().sendCommand(this.name, text); commands.add(text); if (commands.size() > 25) { commands.remove(0); diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/GUI.java b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/GUI.java index 098c872..c56b869 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/GUI.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/GUI.java @@ -1,5 +1,7 @@ package net.knarcraft.minecraftserverlauncher.userinterface; +import java.io.File; + /** * Describes a generic GUI */ @@ -42,4 +44,12 @@ public interface GUI { */ void showMessage(String message); + /** + * Asks the user for a directory as a file object + * + * @param prompt

The prompt to show the user

+ * @return

The directory given by the user

+ */ + File askForDirectory(String prompt); + } diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/MessageHandler.java b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/MessageHandler.java index 6c09f5a..7366b15 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/MessageHandler.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/MessageHandler.java @@ -2,6 +2,9 @@ package net.knarcraft.minecraftserverlauncher.userinterface; import javax.swing.*; +/** + * This class handles displaying messages to the user + */ public abstract class MessageHandler implements GUI { private final boolean silent; diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherGUI.java b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherGUI.java index 77eb499..69f8849 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherGUI.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherGUI.java @@ -2,6 +2,7 @@ package net.knarcraft.minecraftserverlauncher.userinterface; import net.knarcraft.minecraftserverlauncher.Main; import net.knarcraft.minecraftserverlauncher.profile.Collection; +import net.knarcraft.minecraftserverlauncher.profile.Controller; import net.knarcraft.minecraftserverlauncher.profile.Profile; import net.knarcraft.minecraftserverlauncher.server.Server; import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions; @@ -62,6 +63,7 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, private String aboutText; private SystemTray tray; private TrayIcon trayIcon; + private Controller controller; /** * Creates the application window @@ -70,6 +72,7 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, super(false); initialize(440, 170); loadMessages(); + this.controller = Main.getController(); this.globalPlayers = new ArrayList<>(); } @@ -83,6 +86,7 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, super(false); initialize(width, height); loadMessages(); + this.controller = Main.getController(); this.globalPlayers = new ArrayList<>(); } @@ -105,6 +109,21 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, } } + @Override + public File askForDirectory(String prompt) { + JFileChooser chooser = new JFileChooser(); + chooser.setCurrentDirectory(new java.io.File(".")); + chooser.setDialogTitle(prompt); + chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + chooser.setAcceptAllFileFilterUsed(false); + + if (chooser.showOpenDialog(null) != JFileChooser.APPROVE_OPTION) { + setStatus("Choice aborted by user"); + return null; + } + return chooser.getSelectedFile(); + } + /** * Adds a player to the global playerlist, and updates the players combo. * @@ -129,10 +148,12 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, * Updates the profiles combo. */ public void updateProfiles() { + String selectedProfile = Main.getController().getCurrentProfile().getName(); this.profiles.removeAllItems(); - for (Profile profile : Profile.getProfiles()) { - this.profiles.addItem(profile.getName()); + for (String profile : Main.getController().getProfileNames()) { + this.profiles.addItem(profile); } + this.profiles.setSelectedItem(selectedProfile); } /** @@ -148,16 +169,15 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, * Updates ServerLauncherGUI according to current profile settings. */ public void update() { + Controller controller = Main.getController(); serversPane.removeAll(); - for (Collection collection : Profile.getCurrent().getCollections()) { - serversPane.addTab(collection.getName(), collection.getServerTab().getPanel()); - } - chckbxmntmRunInBackground.setState(Profile.getCurrent().getRunInBackground()); - chckbxmntmDelayStartup.setState(Profile.getCurrent().getDelayStartup() > 0); - chckbxmntmDownloadJars.setState(Profile.getCurrent().getDownloadAllAvailableJARFiles()); + chckbxmntmRunInBackground.setState(controller.getRunInBackground()); + chckbxmntmDelayStartup.setState(controller.getDelayStartup() > 0); + chckbxmntmDownloadJars.setState(controller.getDownloadAllJars()); this.targetServer.removeAllItems(); this.targetServer.addItem("All"); - for (Collection collection : Profile.getCurrent().getCollections()) { + for (Collection collection : controller.getCurrentProfile().getCollections()) { + serversPane.addTab(collection.getName(), collection.getServerTab().getPanel()); this.targetServer.addItem(collection.getName()); } } @@ -453,11 +473,7 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, trayIcon.setImageAutoSize(true); ActionListener exitListener = e -> { stop(); - try { - Profile.getCurrent().save(); - } catch (FileNotFoundException e1) { - e1.printStackTrace(); - } + controller.saveState(); System.exit(0); }; @@ -481,7 +497,7 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { - if (Profile.getCurrent().getRunInBackground() && SystemTray.isSupported()) { + if (controller.getRunInBackground() && SystemTray.isSupported()) { try { tray.add(trayIcon); frame.setVisible(false); @@ -490,11 +506,7 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, } } else { stop(); - try { - Profile.getCurrent().save(); - } catch (FileNotFoundException e1) { - e1.printStackTrace(); - } + controller.saveState(); System.exit(0); } } @@ -514,11 +526,7 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { - try { - Profile.getCurrent().save(); - } catch (FileNotFoundException e1) { - e1.printStackTrace(); - } + controller.saveState(); stop(); System.exit(0); } @@ -572,68 +580,60 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, } else if (e.getSource() == mntmStory) { CommonFunctions.goToURL("https://archive.knarcraft.net/Scripts/BungeeMinecraftServerLauncherStory/"); } else if (e.getSource() == btnStartServer) { - try { - Profile.getCurrent().save(); - } catch (FileNotFoundException e1) { - e1.printStackTrace(); - } + controller.saveState(); Executors.newSingleThreadExecutor().execute(Server::startServers); } else if (e.getSource() == btnStopServer) { stop(); } else if (e.getSource() == addServer) { String serverName = JOptionPane.showInputDialog("Name of server: "); try { - Profile.getCurrent().addCollection(serverName); + controller.getCurrentProfile().addCollection(serverName); } catch (ConfigurationException e1) { e1.printStackTrace(); } this.update(); - Profile.getCurrent().updateConsoles(); + controller.getCurrentProfile().updateConsoles(); } else if (e.getSource() == backup) { - backup(); + CommonFunctions.backup(this); } else if (e.getSource() == addProfile) { - Profile.addProfile(JOptionPane.showInputDialog("Profile name: ")); + controller.addProfile(JOptionPane.showInputDialog("Profile name: ")); updateProfiles(); } else if (e.getSource() == delProfile) { Object selected = profiles.getSelectedItem(); if (selected != null) { - Profile.removeProfile(selected.toString()); + controller.removeProfile(selected.toString()); updateProfiles(); } } else if (e.getSource() == profiles) { - try { - changeProfile(); - } catch (FileNotFoundException e1) { - e1.printStackTrace(); - } + changeProfile(); } else if (e.getSource() == btnKick) { if (selectedServerValue != null && selectedPlayerValue != null) { - Profile.getCurrent().sendCommand(selectedServerValue, "kick " + selectedPlayerValue); + controller.getCurrentProfile().sendCommand(selectedServerValue, "kick " + selectedPlayerValue); } } else if (e.getSource() == btnBan) { if (selectedServerValue != null && selectedPlayerValue != null) { - Profile.getCurrent().sendCommand(selectedServerValue, "ban " + selectedPlayerValue); + controller.getCurrentProfile().sendCommand(selectedServerValue, "ban " + selectedPlayerValue); } } else if (e.getSource() == btnOp) { if (selectedServerValue != null && selectedPlayerValue != null) { - Profile.getCurrent().sendCommand(selectedServerValue, "op " + selectedPlayerValue); + controller.getCurrentProfile().sendCommand(selectedServerValue, "op " + selectedPlayerValue); } } else if (e.getSource() == btnDeop) { if (selectedServerValue != null && selectedPlayerValue != null) { - Profile.getCurrent().sendCommand(selectedServerValue, "deop " + selectedPlayerValue); + controller.getCurrentProfile().sendCommand(selectedServerValue, "deop " + selectedPlayerValue); } } else if (e.getSource() == btnCustomCommand) { if (selectedServerValue != null) { - Profile.getCurrent().sendCommand(selectedServerValue, customCommand.getText()); + controller.getCurrentProfile().sendCommand(selectedServerValue, customCommand.getText()); customCommand.setText(""); } } else if (e.getSource() == btnSaveserver) { if (selectedServerValue != null) { - Profile.getCurrent().sendCommand(selectedServerValue, "save-all"); + controller.getCurrentProfile().sendCommand(selectedServerValue, "save-all"); } } else if (e.getSource() == btnReload) { if (selectedServerValue != null) { - Profile.getCurrent().sendCommand(selectedServerValue, "reload"); + controller.getCurrentProfile().sendCommand(selectedServerValue, "reload"); } } else if (e.getSource() == btnServerConsoles) { ServerConsoles.setAsVisible(); @@ -661,14 +661,14 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, /** * Saves the previous profile and loads data from the new profile. */ - private void changeProfile() throws FileNotFoundException { - Profile.getCurrent().save(); + private void changeProfile() { + controller.saveState(); Object current = this.profiles.getSelectedItem(); if (current != null) { - Profile.setCurrent(current.toString()); + controller.setCurrentProfile(current.toString()); } this.update(); - Profile.getCurrent().updateConsoles(); + controller.getCurrentProfile().updateConsoles(); } /** @@ -690,11 +690,15 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, private void delay() { Object selected = profiles.getSelectedItem(); if (selected != null) { - Profile profile = Profile.getProfile(selected.toString()); + Profile profile = controller.getProfileByName(selected.toString()); if (chckbxmntmDelayStartup.isSelected()) { - Objects.requireNonNull(profile).setDelayStartup( - Integer.parseInt(JOptionPane.showInputDialog("Seconds to delay: ")) - ); + String response = JOptionPane.showInputDialog("Seconds to delay: "); + if (response == null) { + chckbxmntmDelayStartup.setState(false); + return; + } + int parsed = Integer.parseInt(response); + Objects.requireNonNull(profile).setDelayStartup(parsed); } else { Objects.requireNonNull(profile).setDelayStartup(0); } @@ -709,7 +713,7 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, private void background() { Object selected = profiles.getSelectedItem(); if (selected != null) { - Profile profile = Profile.getProfile(selected.toString()); + Profile profile = controller.getProfileByName(selected.toString()); Objects.requireNonNull(profile).setRunInBackground(chckbxmntmRunInBackground.isSelected()); } else { showError("No profile selected"); @@ -722,47 +726,12 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, private void downloadJars() { Object selected = profiles.getSelectedItem(); if (selected != null) { - Profile profile = Profile.getProfile(selected.toString()); - Objects.requireNonNull(profile).setDownloadAllAvailableJARFiles(chckbxmntmDownloadJars.isSelected()); + controller.setDownloadAllJars(chckbxmntmDownloadJars.isSelected()); } else { showError("No profile selected"); } } - /** - * Copies all server directories to a folder specified by the user. - */ - private void backup() { - JFileChooser chooser = new JFileChooser(); - chooser.setCurrentDirectory(new java.io.File(".")); - chooser.setDialogTitle("Backup folder"); - chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - chooser.setAcceptAllFileFilterUsed(false); - if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { - File path = chooser.getSelectedFile(); - for (Collection collection : Profile.getCurrent().getCollections()) { - if (!collection.getServer().getPath().equals("") && collection.getServer().isEnabled()) { - String name = collection.getServer().getName(); - File srcFolder = new File(collection.getServer().getPath()); - File destFolder = new File(path, name); - if (!destFolder.exists()) { - if (destFolder.mkdirs()) { - try { - CommonFunctions.copyFolder(this, srcFolder, destFolder); - } catch (IOException e) { - e.printStackTrace(); - return; - } - } else { - return; - } - } - } - } - } - this.setStatus("Backup finished"); - } - /** * Updates the list of players currently online on the selected server, */ @@ -777,7 +746,7 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, targetPlayer.addItem(player); } } else { - for (String player : Profile.getCurrent().getCollection(selectedServerValue).getServer().getPlayers()) { + for (String player : controller.getCurrentProfile().getCollection(selectedServerValue).getServer().getPlayers()) { targetPlayer.addItem(player); } } diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerTab.java b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerTab.java index 3bfa868..30d4054 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerTab.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerTab.java @@ -1,6 +1,6 @@ package net.knarcraft.minecraftserverlauncher.userinterface; -import net.knarcraft.minecraftserverlauncher.profile.Profile; +import net.knarcraft.minecraftserverlauncher.Main; import net.knarcraft.minecraftserverlauncher.server.Server; import net.knarcraft.minecraftserverlauncher.server.ServerTypeHandler; import net.knarcraft.minecraftserverlauncher.server.servertypes.ServerType; @@ -29,7 +29,7 @@ public class ServerTab implements ActionListener { public ServerTab(String name) throws ConfigurationException { this.name = name; panel = new JPanel(); - Profile.getGUI().getPane().addTab(name, null, panel, null); + Main.getController().getGUI().getPane().addTab(name, null, panel, null); SpringLayout sl_panel_3 = new SpringLayout(); panel.setLayout(sl_panel_3); @@ -197,9 +197,9 @@ public class ServerTab implements ActionListener { * Removes the collection containing this ServerTab, and updates everything necessary. */ private void remove() { - Profile.getCurrent().removeCollection(this.name); - Profile.getGUI().update(); - Profile.getCurrent().updateConsoles(); + Main.getController().getCurrentProfile().removeCollection(this.name); + Main.getController().getGUI().update(); + Main.getController().getCurrentProfile().updateConsoles(); } /** diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/utility/CommonFunctions.java b/src/main/java/net/knarcraft/minecraftserverlauncher/utility/CommonFunctions.java index ff8dc93..824efd3 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/utility/CommonFunctions.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/utility/CommonFunctions.java @@ -1,7 +1,9 @@ package net.knarcraft.minecraftserverlauncher.utility; import net.knarcraft.minecraftserverlauncher.Main; -import net.knarcraft.minecraftserverlauncher.userinterface.ServerLauncherGUI; +import net.knarcraft.minecraftserverlauncher.profile.Collection; +import net.knarcraft.minecraftserverlauncher.server.Server; +import net.knarcraft.minecraftserverlauncher.userinterface.GUI; import java.io.*; import java.net.URI; @@ -21,7 +23,7 @@ import java.util.Scanner; */ public final class CommonFunctions { - private static String filesDirectory = Main.getApplicationWorkDirectory() + File.separator + "files"; + private static final String filesDirectory = Main.getApplicationWorkDirectory() + File.separator + "files"; /** * Creates all folders necessary for tests and normal operation @@ -128,7 +130,7 @@ public final class CommonFunctions { * @param destination

Target destination

* @throws IOException

If we can't start a file stream

*/ - public static void copyFolder(ServerLauncherGUI serverLauncherGui, File source, File destination) throws IOException { + public static void copyFolder(GUI serverLauncherGui, File source, File destination) throws IOException { if (!source.isDirectory()) { copyFile(serverLauncherGui, source, destination); } else { @@ -156,7 +158,7 @@ public final class CommonFunctions { * @param destination

The location of the copied file

* @throws IOException

If reading or writing fails

*/ - private static void copyFile(ServerLauncherGUI serverLauncherGui, File source, File destination) throws IOException { + private static void copyFile(GUI serverLauncherGui, File source, File destination) throws IOException { serverLauncherGui.setStatus("Copying file " + source + "..."); InputStream in = new FileInputStream(source); OutputStream out = new FileOutputStream(destination); @@ -199,4 +201,43 @@ public final class CommonFunctions { } return text.toString().trim(); } + + /** + * Copies all server directories to a folder specified by the user. + */ + public static void backup(GUI gui) { + File path = gui.askForDirectory("Backup folder"); + for (Collection collection : Main.getController().getCurrentProfile().getCollections()) { + //Ignore disabled and invalid servers + if (collection.getServer().getPath().equals("") || !collection.getServer().isEnabled()) { + continue; + } + //Decide sub-folders + Server targetServer = collection.getServer(); + String name = targetServer.getName(); + File srcFolder = new File(targetServer.getPath()); + File destinationFolder = new File(path, name); + //Create child folders + if (!destinationFolder.exists() && !destinationFolder.mkdirs()) { + throw new IllegalArgumentException("Unable to create necessary sub-folder in the backup folder"); + } + //Backup + try { + CommonFunctions.copyFolder(gui, srcFolder, destinationFolder); + } catch (IOException e) { + e.printStackTrace(); + } + } + gui.setStatus("Backup finished"); + } + + /** + * Validates that a name is not empty and does not contain invalid characters + * + * @param name

The name to check

+ * @return

True if the name is valid

+ */ + public static boolean nameIsValid(String name) { + return !name.equals("") && name.matches("[^!?;,]+"); + } } diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/utility/JarDownloader.java b/src/main/java/net/knarcraft/minecraftserverlauncher/utility/JarDownloader.java index f9785ed..48f2313 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/utility/JarDownloader.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/utility/JarDownloader.java @@ -15,7 +15,7 @@ import java.io.IOException; public final class JarDownloader { private final String jarDirectory; - private GUI gui; + private final GUI gui; /** * Initializes a jar downloader diff --git a/src/main/resources/servertypes.csv b/src/main/resources/servertypes.csv index 0e6ac59..b114d17 100644 --- a/src/main/resources/servertypes.csv +++ b/src/main/resources/servertypes.csv @@ -6,5 +6,5 @@ Paper;1.16.1,1.15.2,1.14.4,1.13.2,1.12.2,1.11.2,1.10.2,1.9.4,1.8.8;https://stati Bungee;Latest;https://ci.md-5.net/job/BungeeCord/lastSuccessfulBuild/artifact/bootstrap/target/;Artifacts of BungeeCord #; ;http://ci.md-5.net/job/BungeeCord/lastSuccessfulBuild/artifact/bootstrap/target/BungeeCord.jar Waterfall;Latest;https://papermc.io/api/v1/waterfall/1.16;"latest":";";https://papermc.io/api/v1/waterfall/1.16/ Travertine;Latest;https://papermc.io/api/v1/travertine/1.16;"latest":";";https://papermc.io/api/v1/travertine/1.16/ -Vanilla;Latest,Snapshot,1.16.1,1.15.2,1.14.4,1.13.2,1.12.2,1.11.2,1.10.2,1.9.4,1.8.9,1.7.10,1.6.4,1.5.2,1.4.7,1.3.2,1.2.5;https://launchermeta.mojang.com/mc/game/version_manifest.json;"release":";";https://s3.amazonaws.com/Minecraft.Download/versions/ +Vanilla;Latest,Snapshot,1.16.2,1.15.2,1.14.4,1.13.2,1.12.2,1.11.2,1.10.2,1.9.4,1.8.9,1.7.10,1.6.4,1.5.2,1.4.7,1.3.2,1.2.5;https://launchermeta.mojang.com/mc/game/version_manifest.json;"release":";";https://s3.amazonaws.com/Minecraft.Download/versions/ Custom;; \ No newline at end of file diff --git a/src/test/java/net/knarcraft/minecraftserverlauncher/server/ServerTest.java b/src/test/java/net/knarcraft/minecraftserverlauncher/server/ServerTest.java new file mode 100644 index 0000000..119a1ee --- /dev/null +++ b/src/test/java/net/knarcraft/minecraftserverlauncher/server/ServerTest.java @@ -0,0 +1,23 @@ +package net.knarcraft.minecraftserverlauncher.server; + +import org.junit.Test; + +import javax.naming.ConfigurationException; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertFalse; + +public class ServerTest { + + @Test + public void fromStringTest() throws ConfigurationException { + Server server = Server.fromString("asd;/home/;false;Bukkit;1.10.2;4G;"); + assertEquals("asd", server.getName()); + assertEquals("/home/", server.getPath()); + assertFalse(server.isEnabled()); + assertEquals("Bukkit", server.getTypeName()); + assertEquals("1.10.2", server.getServerVersion()); + assertEquals("4G", server.getMaxRam()); + } + +} diff --git a/src/test/java/net/knarcraft/minecraftserverlauncher/server/ServerVersionContainerTest.java b/src/test/java/net/knarcraft/minecraftserverlauncher/server/ServerVersionContainerTest.java index 9756246..c60ece9 100644 --- a/src/test/java/net/knarcraft/minecraftserverlauncher/server/ServerVersionContainerTest.java +++ b/src/test/java/net/knarcraft/minecraftserverlauncher/server/ServerVersionContainerTest.java @@ -13,7 +13,7 @@ import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.crea public class ServerVersionContainerTest { private final String filesDirectory = Main.getApplicationWorkDirectory() + File.separator + "files"; - private String versionFile = filesDirectory + File.separator + "versions.csv"; + private final String versionFile = filesDirectory + File.separator + "versions.csv"; private ServerVersionContainer serverVersionContainer; @Before diff --git a/src/test/java/net/knarcraft/minecraftserverlauncher/userinterface/FakeGUI.java b/src/test/java/net/knarcraft/minecraftserverlauncher/userinterface/FakeGUI.java index 024699c..b77787e 100644 --- a/src/test/java/net/knarcraft/minecraftserverlauncher/userinterface/FakeGUI.java +++ b/src/test/java/net/knarcraft/minecraftserverlauncher/userinterface/FakeGUI.java @@ -1,5 +1,7 @@ package net.knarcraft.minecraftserverlauncher.userinterface; +import java.io.File; + public class FakeGUI extends MessageHandler implements GUI { /*** @@ -13,4 +15,9 @@ public class FakeGUI extends MessageHandler implements GUI { public void setStatus(String message) { System.out.println(message); } + + @Override + public File askForDirectory(String prompt) { + return null; + } } diff --git a/src/test/java/net/knarcraft/minecraftserverlauncher/utility/CommonFunctionsTest.java b/src/test/java/net/knarcraft/minecraftserverlauncher/utility/CommonFunctionsTest.java index 6a74f0f..1e90b9f 100644 --- a/src/test/java/net/knarcraft/minecraftserverlauncher/utility/CommonFunctionsTest.java +++ b/src/test/java/net/knarcraft/minecraftserverlauncher/utility/CommonFunctionsTest.java @@ -1,19 +1,17 @@ package net.knarcraft.minecraftserverlauncher.utility; -import net.knarcraft.minecraftserverlauncher.profile.Profile; +import net.knarcraft.minecraftserverlauncher.Main; import org.junit.Test; -import java.io.FileNotFoundException; - import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.stringBetween; import static org.junit.Assert.assertEquals; public class CommonFunctionsTest { @Test - public void saveProfileTest() throws FileNotFoundException { - Profile.addProfile("Test"); - Profile.getCurrent().save(); + public void saveProfileTest() { + Main.getController().addProfile("Test"); + Main.getController().saveState(); } @Test