Makes the project into a Maven project
Some checks failed
KnarCraft/Minecraft-Server-Launcher/master There was a failure building this commit
Some checks failed
KnarCraft/Minecraft-Server-Launcher/master There was a failure building this commit
Moves stuff around Adds Jenkinsfile Changes some package names Replaces library with Maven dependency
This commit is contained in:
267
src/main/java/net/knarcraft/minecraftserverlauncher/Main.java
Normal file
267
src/main/java/net/knarcraft/minecraftserverlauncher/Main.java
Normal file
@ -0,0 +1,267 @@
|
||||
package net.knarcraft.minecraftserverlauncher;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import net.knarcraft.minecraftserverlauncher.profile.Collection;
|
||||
import net.knarcraft.minecraftserverlauncher.profile.Profile;
|
||||
import net.knarcraft.minecraftserverlauncher.server.Server;
|
||||
import net.knarcraft.minecraftserverlauncher.server.ServerType;
|
||||
import net.knarcraft.minecraftserverlauncher.userinterface.ServerConsoles;
|
||||
|
||||
import javax.naming.ConfigurationException;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Scanner;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static net.knarcraft.minecraftserverlauncher.Shared.downloadFile;
|
||||
import static net.knarcraft.minecraftserverlauncher.Shared.readFile;
|
||||
import static net.knarcraft.minecraftserverlauncher.Shared.stringBetween;
|
||||
//Java 8 required.
|
||||
|
||||
/**
|
||||
* A software for managing Minecraft servers.
|
||||
*
|
||||
* @author Kristian Knarvik <kristian.knarvik@knett.no>
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
public class Main {
|
||||
private static String appDir;
|
||||
private static boolean running = false;
|
||||
private static final String updateChannel = "alpha";
|
||||
private static final String updateURL = "https://api.knarcraft.net/minecraftserverlauncher";
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
checkForUpdate();
|
||||
try (PrintWriter file = new PrintWriter(Main.getAppDir() + File.separator + "latestrun.log")) {
|
||||
file.print("");
|
||||
} catch (IOException e ) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
EventQueue.invokeLater(() -> {
|
||||
try {
|
||||
setup();
|
||||
new ServerConsoles();
|
||||
Profile.load();
|
||||
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
|
||||
exec.scheduleAtFixedRate(Main::updateConsoles, 10, 500, TimeUnit.MILLISECONDS);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all server types, so that they are ready for use
|
||||
*/
|
||||
private static void setup() {
|
||||
try {
|
||||
ServerType.loadServerTypes();
|
||||
} catch (ConfigurationException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the directory the .jar file is running from
|
||||
*
|
||||
* @return A string path
|
||||
*/
|
||||
public static String getAppDir() {
|
||||
if (appDir == null) {
|
||||
try {
|
||||
appDir = String.valueOf(new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParentFile());
|
||||
} catch (URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
return appDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads from server processes, and writes the output to consoles.
|
||||
*/
|
||||
private static void updateConsoles() {
|
||||
try {
|
||||
for (Collection collection : Profile.getCurrent().getCollections()) {
|
||||
Server server = collection.getServer();
|
||||
if (server.isEnabled() && server.getProcess() != null) {
|
||||
try {
|
||||
String readText = server.read();
|
||||
if (!readText.equals("")) {
|
||||
collection.getServerConsole().output(readText);
|
||||
updatePlayerList(readText, server);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (!server.getProcess().isAlive()) {
|
||||
server.stopped();
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean runningNew = serversRunning();
|
||||
if (!runningNew && running) {
|
||||
Profile.getGUI().updateRunning(false);
|
||||
Profile.getGUI().setStatus("Servers are stopped");
|
||||
} else if (runningNew && !running) {
|
||||
Profile.getGUI().updateRunning(true);
|
||||
}
|
||||
running = runningNew;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Goes through all servers and looks for any running servers.
|
||||
*
|
||||
* @return Is at least one server running?
|
||||
*/
|
||||
private static boolean serversRunning() {
|
||||
int num = 0;
|
||||
for (Collection collection : Profile.getCurrent().getCollections()) {
|
||||
if (collection.getServer().isStarted() || (collection.getServer().getProcess() != null && collection.getServer().getProcess().isAlive())) {
|
||||
num++;
|
||||
}
|
||||
}
|
||||
return num > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for strings implying a player has joined or left, and updates the appropriate lists.
|
||||
*
|
||||
* @param text The text to search.
|
||||
* @param server The server which sent the text.
|
||||
*/
|
||||
private static void updatePlayerList(String text, Server server) {
|
||||
if (!server.getTypeName().equals("Bungee")) {
|
||||
String joinedPlayer = getPlayer(text, true);
|
||||
String leftPlayer = getPlayer(text, false);
|
||||
if (!joinedPlayer.equals("")) {
|
||||
if (!server.hasPlayer(joinedPlayer)) {
|
||||
server.addPlayer(joinedPlayer);
|
||||
}
|
||||
} else if (!leftPlayer.equals("")) {
|
||||
if (server.hasPlayer(leftPlayer)) {
|
||||
server.removePlayer(leftPlayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches a string for players joining or leaving.
|
||||
*
|
||||
* @param text The string to search
|
||||
* @param joined Are we searching for a joining player or not
|
||||
* @return The name of a player or an empty string
|
||||
*/
|
||||
private static String getPlayer(String text, boolean joined) {
|
||||
String playerName;
|
||||
if (joined) {
|
||||
playerName = stringBetween(text, "[Server thread/INFO]: ", " joined the game");
|
||||
if (playerName.equals("")) {
|
||||
playerName = stringBetween(text, "UUID of player ", " is ");
|
||||
}
|
||||
} else {
|
||||
playerName = stringBetween(text, "INFO]: ", " lost connection");
|
||||
if (playerName.equals("")) {
|
||||
playerName = stringBetween(text, "[Server thread/INFO]: ", " left the game");
|
||||
}
|
||||
}
|
||||
return playerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a newer version is available
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void checkForUpdate() throws IOException {
|
||||
Scanner file;
|
||||
try {
|
||||
file = new Scanner(new File("config/currentversion.csv"));
|
||||
} catch (FileNotFoundException e) {
|
||||
file = new Scanner(Main.class.getResourceAsStream("/config/currentversion.csv"));
|
||||
}
|
||||
|
||||
String oldType = file.nextLine();
|
||||
String oldVer = file.nextLine();
|
||||
file.close();
|
||||
|
||||
String data = readFile(updateURL);
|
||||
JsonObject jsonObject = new JsonParser().parse(data).getAsJsonObject();
|
||||
String latest = jsonObject.getAsJsonObject("latest").get(updateChannel).getAsString();
|
||||
|
||||
if (!oldType.equals(updateChannel) || !oldVer.equals(latest)) {
|
||||
String dir = getAppDir() + File.separator;
|
||||
JsonArray versionList = jsonObject.getAsJsonArray("versions");
|
||||
String url = "";
|
||||
for (JsonElement elem : versionList) {
|
||||
JsonObject obj = elem.getAsJsonObject();
|
||||
String ver = obj.get("id").getAsString();
|
||||
String type = obj.get("type").getAsString();
|
||||
if (ver.equals(latest) && type.equals(updateChannel)) {
|
||||
url = obj.get("url").getAsString();
|
||||
}
|
||||
}
|
||||
if (downloadFile(url, new File(dir + "update.jar").toPath())) {
|
||||
doUpdate(dir);
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"An update is available, but could not be downloaded.",
|
||||
"Update available",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void doUpdate(String dir) {
|
||||
int answer = JOptionPane.showConfirmDialog(
|
||||
null,
|
||||
"An update is available. Do you want to update?",
|
||||
"Update available",
|
||||
JOptionPane.YES_NO_OPTION
|
||||
);
|
||||
if (answer == JOptionPane.YES_NO_OPTION) {
|
||||
if (new File (dir + "Minecraft-Server-Launcher.jar").renameTo(new File(dir + "Old.jar"))) {
|
||||
if (new File(dir + "update.jar").renameTo(new File (dir + "Minecraft-Server-Launcher.jar"))) {
|
||||
if (new File(dir + "Old.jar").delete()) {
|
||||
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"Update finished. Please run the software again.",
|
||||
"Update complete",
|
||||
JOptionPane.INFORMATION_MESSAGE
|
||||
);
|
||||
System.exit(0);
|
||||
}
|
||||
} else {
|
||||
if (!new File(dir + "Old.jar").renameTo(new File (dir + "Minecraft-Server-Launcher.jar"))) {
|
||||
System.out.println("Shit");
|
||||
}
|
||||
}
|
||||
}
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"Could not replace the main .jar with the downloaded .jar.",
|
||||
"Update failed",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package net.knarcraft.minecraftserverlauncher;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* A holding class for methods shared between classes.
|
||||
*
|
||||
* @author Kristian Knarvik <kristian.knarvik@knett.no>
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class Shared {
|
||||
/**
|
||||
* Finds a substring between two substrings in a string.
|
||||
*
|
||||
* @param string The string containing the substrings
|
||||
* @param start The substring before the wanted substring
|
||||
* @param end The substring after the wanted substring
|
||||
* @return The wanted substring.
|
||||
*/
|
||||
public static String stringBetween(String string, String start, String end) {
|
||||
int startPos = string.indexOf(start) + start.length();
|
||||
if (!string.contains(start) || string.indexOf(end, startPos) < startPos) {
|
||||
return "";
|
||||
}
|
||||
return string.substring(startPos, string.indexOf(end, startPos));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a file from a website.
|
||||
* This is used to find the newest version of jars and the software.
|
||||
*
|
||||
* @param path The full url of the file to read
|
||||
* @return True if successful. False otherwise
|
||||
*/
|
||||
public static String readFile(String path) throws IOException {
|
||||
URL url = new URL(path);
|
||||
return new Scanner(url.openStream()).useDelimiter("\\Z").next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads a file from a website.
|
||||
*
|
||||
* @param path The full url of the file to download.
|
||||
* @param outfile The file to save to
|
||||
* @return True if successful. False otherwise
|
||||
*/
|
||||
public static boolean downloadFile(String path, Path outfile) {
|
||||
try {
|
||||
URL url = new URL(path);
|
||||
InputStream in = url.openStream();
|
||||
Files.copy(in, outfile, StandardCopyOption.REPLACE_EXISTING);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package net.knarcraft.minecraftserverlauncher.profile;
|
||||
|
||||
import net.knarcraft.minecraftserverlauncher.userinterface.ServerTab;
|
||||
import net.knarcraft.minecraftserverlauncher.server.Server;
|
||||
import net.knarcraft.minecraftserverlauncher.userinterface.ServerConsoles;
|
||||
import net.knarcraft.minecraftserverlauncher.userinterface.Console;
|
||||
|
||||
/**
|
||||
* Acts as a wrapper for objects necessary for each server.
|
||||
*
|
||||
* @author Kristian Knarvik <kristian.knarvik@knett.no>
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class Collection {
|
||||
private final Server server;
|
||||
private final ServerTab serverTab;
|
||||
private final Console serverConsole;
|
||||
private final String name;
|
||||
|
||||
Collection(String name) {
|
||||
this.serverTab = new ServerTab(name);
|
||||
this.server = new Server(name);
|
||||
this.serverConsole = ServerConsoles.addTab(name);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
Collection(String name,
|
||||
String path,
|
||||
boolean enabled,
|
||||
String typeName,
|
||||
String serverVersion,
|
||||
String maxRam,
|
||||
String vanillaVersion,
|
||||
String snapshotVersion,
|
||||
String spongeVanillaVersion,
|
||||
String bungeeVersion
|
||||
) {
|
||||
this.serverTab = new ServerTab(name);
|
||||
this.server = new Server(
|
||||
name,
|
||||
path,
|
||||
enabled,
|
||||
typeName,
|
||||
serverVersion,
|
||||
maxRam,
|
||||
vanillaVersion,
|
||||
snapshotVersion,
|
||||
spongeVanillaVersion,
|
||||
bungeeVersion
|
||||
);
|
||||
this.serverConsole = ServerConsoles.addTab(name);
|
||||
this.name = name;
|
||||
this.serverTab.setData(path, enabled, typeName, serverVersion, maxRam);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public Server getServer() {
|
||||
return this.server;
|
||||
}
|
||||
|
||||
public ServerTab getServerTab() {
|
||||
return this.serverTab;
|
||||
}
|
||||
|
||||
public Console getServerConsole() {
|
||||
return this.serverConsole;
|
||||
}
|
||||
}
|
@ -0,0 +1,640 @@
|
||||
package net.knarcraft.minecraftserverlauncher.profile;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import net.knarcraft.minecraftserverlauncher.userinterface.GUI;
|
||||
import net.knarcraft.minecraftserverlauncher.userinterface.ServerConsoles;
|
||||
import net.knarcraft.minecraftserverlauncher.userinterface.ServerTab;
|
||||
import net.knarcraft.minecraftserverlauncher.server.AdvancedServerType;
|
||||
import net.knarcraft.minecraftserverlauncher.server.Server;
|
||||
import net.knarcraft.minecraftserverlauncher.server.ServerType;
|
||||
import net.knarcraft.minecraftserverlauncher.Main;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.*;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
import java.util.Scanner;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static net.knarcraft.minecraftserverlauncher.Shared.downloadFile;
|
||||
import static net.knarcraft.minecraftserverlauncher.Shared.readFile;
|
||||
import static net.knarcraft.minecraftserverlauncher.Shared.stringBetween;
|
||||
|
||||
/**
|
||||
* Contains all user settings, and a list of servers.
|
||||
*
|
||||
* @author Kristian Knarvik <kristian.knarvik@knett.no>
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class Profile {
|
||||
private static final ArrayList<Profile> profiles = new ArrayList<>();
|
||||
private static Profile current;
|
||||
private static GUI gui;
|
||||
private static final String profilesDir = Main.getAppDir() + File.separator + "files";
|
||||
private static final String profilesFile = Main.getAppDir() + File.separator + "files" + File.separator + "Profiles.txt";
|
||||
private static final String jarDir = Main.getAppDir() + File.separator + "files" + File.separator + "Jars" + File.separator;
|
||||
|
||||
private final ArrayList<Collection> collections;
|
||||
private final String name;
|
||||
private boolean runInBackground;
|
||||
private int delayStartup;
|
||||
private boolean downloadJars;
|
||||
private static String vanillaVersion;
|
||||
private static String snapshotVersion;
|
||||
private static String bungeeVersion;
|
||||
|
||||
private Profile(String name) {
|
||||
this.collections = new ArrayList<>();
|
||||
this.name = name;
|
||||
this.runInBackground = false;
|
||||
this.delayStartup = 0;
|
||||
this.downloadJars = false;
|
||||
profiles.add(this);
|
||||
if (current == null) {
|
||||
current = this;
|
||||
}
|
||||
}
|
||||
|
||||
private Profile(String name, boolean runInBackground, int delayStartup, boolean downloadJars) {
|
||||
this.collections = new ArrayList<>();
|
||||
this.name = name;
|
||||
this.runInBackground = runInBackground;
|
||||
this.delayStartup = delayStartup;
|
||||
this.downloadJars = downloadJars;
|
||||
profiles.add(this);
|
||||
if (current == null) {
|
||||
current = this;
|
||||
}
|
||||
}
|
||||
|
||||
public static GUI getGUI() {
|
||||
return gui;
|
||||
}
|
||||
|
||||
public boolean getRunInBackground() {
|
||||
return this.runInBackground;
|
||||
}
|
||||
|
||||
public int getDelayStartup() {
|
||||
return this.delayStartup;
|
||||
}
|
||||
|
||||
public boolean getDownloadJars() {
|
||||
return this.downloadJars;
|
||||
}
|
||||
|
||||
public static Profile getCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
public ArrayList<Collection> getCollections() {
|
||||
return this.collections;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Collection object by name.
|
||||
*
|
||||
* @param name The name of the collection.
|
||||
* @return A collection object.
|
||||
*/
|
||||
public Collection getCollection(String name) {
|
||||
for (Collection collection : this.collections) {
|
||||
if (collection.getName().equals(name)) {
|
||||
return collection;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Profile getProfile(String name) {
|
||||
for (Profile profile : profiles) {
|
||||
if (profile.name.equals(name)) {
|
||||
return profile;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ArrayList<Profile> getProfiles() {
|
||||
return profiles;
|
||||
}
|
||||
|
||||
public void setRunInBackground(boolean value) {
|
||||
this.runInBackground = value;
|
||||
}
|
||||
|
||||
public void setDelayStartup(int value) {
|
||||
if (value >= 0) {
|
||||
this.delayStartup = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void setDownloadJars(boolean value) {
|
||||
this.downloadJars = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a collection to the profile if the name is valid.
|
||||
*
|
||||
* @param name The name of the collection and its elements.
|
||||
*/
|
||||
public void addCollection(String name) {
|
||||
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(";")
|
||||
) {
|
||||
collections.add(new Collection(name));
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"A server name must my unique and not empty or \"All\"." +
|
||||
"It can't contain any of the characters \"!\", \"?\" or \";\".",
|
||||
"Error",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.contains("!") && !name.contains("?") && !name.contains(";")) {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"Profile name can't be blank.",
|
||||
"Error",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
return;
|
||||
}
|
||||
for (Profile profile : profiles) {
|
||||
if (profile.name.equals(name)) {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"There is already a profile with this name.",
|
||||
"Error",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
new Profile(name);
|
||||
}
|
||||
|
||||
public void removeCollection(String name) {
|
||||
for (int i = 0; i < collections.size(); i++) {
|
||||
if (collections.get(i).getName().equals(name)) {
|
||||
this.collections.remove(i);
|
||||
gui.update();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeProfile(String name) {
|
||||
if (profiles.size() > 1) {
|
||||
for (int i = 0; i < profiles.size(); i++) {
|
||||
if (profiles.get(i).name.equals((name))) {
|
||||
profiles.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateConsoles() {
|
||||
JTabbedPane consolesTab = ServerConsoles.getTab();
|
||||
consolesTab.removeAll();
|
||||
for (Collection collection : collections) {
|
||||
consolesTab.add(collection.getName(), collection.getServerConsole().getPanel());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a command to a server, or all servers
|
||||
*
|
||||
* @param serverName The target server
|
||||
* @param command The command to send.
|
||||
*/
|
||||
public void sendCommand(String serverName, String command) {
|
||||
if (serverName.equals("All")) {
|
||||
for (Collection collection : this.collections) {
|
||||
try {
|
||||
collection.getServer().sendCommand(command);
|
||||
} catch (IOException e) {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"Server " + collection.getName() + " caused an exception.",
|
||||
"Error",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Collection collection = getCollection(serverName);
|
||||
if (collection != null) {
|
||||
Server target = collection.getServer();
|
||||
try {
|
||||
target.sendCommand(command);
|
||||
} catch (IOException e) {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"Server " + target.getName() + " caused an exception.",
|
||||
"Error",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
}
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"Server " + serverName + " is invalid.",
|
||||
"Error", JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
for (Collection collection : this.collections) {
|
||||
Server server = collection.getServer();
|
||||
ServerTab serverTab = collection.getServerTab();
|
||||
server.setPath(serverTab.getPath());
|
||||
server.setMaxRam(serverTab.getMaxRam());
|
||||
server.setType(ServerType.getByName(serverTab.getType()));
|
||||
try {
|
||||
server.setServerVersion(serverTab.getVersion());
|
||||
} catch (IllegalArgumentException e) {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"Invalid server version for " + server.getName(),
|
||||
"Error",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
}
|
||||
server.toggle(serverTab.enabled());
|
||||
}
|
||||
if (!new File(profilesDir).exists() && !new File(profilesDir).mkdirs()) {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"Unable to create the folder " + profilesDir,
|
||||
"Error",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
throw new FileNotFoundException("Unable to create the profiles folder: " + profilesDir);
|
||||
}
|
||||
try (PrintWriter file = new PrintWriter(profilesFile)) {
|
||||
file.println(String.format(
|
||||
"%s;%s;%s;%s;%d;%d",
|
||||
current.name,
|
||||
vanillaVersion,
|
||||
snapshotVersion,
|
||||
bungeeVersion,
|
||||
gui.getSize().width,
|
||||
gui.getSize().height
|
||||
));
|
||||
file.close();
|
||||
for (Profile profile : profiles) {
|
||||
StringBuilder saveString = new StringBuilder(String.format(
|
||||
"%s;%b;%d;%b?",
|
||||
profile.name,
|
||||
profile.runInBackground,
|
||||
profile.delayStartup,
|
||||
profile.downloadJars)
|
||||
);
|
||||
for (Collection collection : profile.collections) {
|
||||
Server server = collection.getServer();
|
||||
saveString.append(String.format(
|
||||
"%s;%s;%b;%s;%s;%s;%s;%s;%s;%s!",
|
||||
server.getName(),
|
||||
server.getPath(),
|
||||
server.isEnabled(),
|
||||
server.getTypeName(),
|
||||
server.getServerVersion(),
|
||||
server.getMaxRam(),
|
||||
server.getVanillaVersion(),
|
||||
server.getSnapshotVersion(),
|
||||
server.getSpongeVanillaVersion(),
|
||||
server.getBungeeVersion()
|
||||
)
|
||||
);
|
||||
}
|
||||
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 (gui != null) {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"Unable to save to file. Try running the software as an administrator.",
|
||||
"Error",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
} 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 (gui != null) {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"Unable to save to file. Try running the software as an administrator.",
|
||||
"Error",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
}
|
||||
throw new FileNotFoundException("Unable to create the profiles file");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads profiles and servers from a text file.
|
||||
*/
|
||||
public static void load() {
|
||||
try (Scanner in = new Scanner(new File(profilesFile))) {
|
||||
try {
|
||||
String[] staticData = in.nextLine().split(";", -1);
|
||||
String profileName = staticData[0];
|
||||
vanillaVersion = staticData[1];
|
||||
snapshotVersion = staticData[2];
|
||||
bungeeVersion = staticData[3];
|
||||
int guiWidth = Integer.parseInt(staticData[4]);
|
||||
int guiHeight = Integer.parseInt(staticData[5]);
|
||||
gui = new GUI(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);
|
||||
}
|
||||
}
|
||||
current = getProfile(profileName);
|
||||
} catch (ArrayIndexOutOfBoundsException | NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"Invalid Profile.txt file. Profiles could not be loaded. If this error persists, please manually delete the file.",
|
||||
"Error",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
System.exit(1);
|
||||
}
|
||||
if (profiles.size() == 0) {
|
||||
addProfile("Default");
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"A profiles file was not found. Default profile was created.",
|
||||
"Info",
|
||||
JOptionPane.INFORMATION_MESSAGE
|
||||
);
|
||||
gui = new GUI();
|
||||
addProfile("Default");
|
||||
}
|
||||
gui.update();
|
||||
gui.updateProfiles();
|
||||
current.updateConsoles();
|
||||
if (current.downloadJars) {
|
||||
Executors.newSingleThreadExecutor().execute(() -> {
|
||||
try {
|
||||
downloadJars();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (current.runInBackground) {
|
||||
Executors.newSingleThreadExecutor().execute(Server::startServers);
|
||||
gui.hide();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a profile, and creates a profile with the data.
|
||||
*
|
||||
* @param profileData The data of the new profile
|
||||
* @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])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a server, and creates a new collection.
|
||||
*
|
||||
* @param profile The profile which to add the collection
|
||||
* @param serverData The data to parse
|
||||
*/
|
||||
private static void parseServer(Profile profile, String[] serverData) {
|
||||
profile.collections.add(new Collection(
|
||||
serverData[0],
|
||||
serverData[1],
|
||||
Boolean.parseBoolean(serverData[2]),
|
||||
serverData[3],
|
||||
serverData[4],
|
||||
serverData[5],
|
||||
serverData[6],
|
||||
serverData[7],
|
||||
serverData[8],
|
||||
serverData[9])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads all jars to the program directory.
|
||||
*
|
||||
* @throws IOException On version file failure or folder creation failure
|
||||
*/
|
||||
public static void downloadJars() throws IOException {
|
||||
if (!new File(jarDir).exists() && !new File(jarDir).mkdirs()) {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"Could not create the Jars folder. Please run the program with admin permissions, or move it to a writable directory.",
|
||||
"Error",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
throw new FileNotFoundException("Unable to create jars folder");
|
||||
}
|
||||
try {
|
||||
downloadAll();
|
||||
printToGui("Finished downloading jars");
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new FileNotFoundException("One or more downloads failed: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints something to the gui status field if the gui exists
|
||||
* Otherwise it prints to the console
|
||||
*
|
||||
* @param str The string to show the user
|
||||
*/
|
||||
private static void printToGui(String str) {
|
||||
if (gui != null) {
|
||||
gui.setStatus(str);
|
||||
} else {
|
||||
System.out.println(str);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads jar files for all possible server versions.
|
||||
*
|
||||
* @throws IOException If a jar fails to download.
|
||||
*/
|
||||
private static void downloadAll() throws IOException {
|
||||
for (ServerType type : ServerType.getServerTypes()) {
|
||||
String url = Objects.requireNonNull(type).getDownloadURL(), name = type.getName(), newestVersion;
|
||||
AdvancedServerType advType = type instanceof AdvancedServerType ? (AdvancedServerType) type : null;
|
||||
for (String version : type.getVersions()) {
|
||||
Boolean success;
|
||||
printToGui("Downloading: " + name + version + ".jar");
|
||||
File file = new File(jarDir + type.getName() + version + ".jar");
|
||||
Path filePath = Paths.get(jarDir + type.getName() + version + ".jar");
|
||||
switch (type.getName()) {
|
||||
case "Vanilla":
|
||||
case "Snapshot":
|
||||
if (version.equals("Latest")) {
|
||||
String versionText = readFile(Objects.requireNonNull(advType).getVersionURL());
|
||||
JsonObject jsonObject = new JsonParser().parse(versionText).getAsJsonObject();
|
||||
String latest = jsonObject.getAsJsonObject("latest").get("release").getAsString();
|
||||
JsonElement ver = jsonObject.getAsJsonArray("versions").get(0);
|
||||
String versionFile = ver.getAsJsonObject().get("url").getAsString();
|
||||
|
||||
versionText = readFile(versionFile);
|
||||
jsonObject = new JsonParser().parse(versionText).getAsJsonObject();
|
||||
String jarFile = jsonObject.getAsJsonObject("downloads").getAsJsonObject("server").get("url").getAsString();
|
||||
|
||||
setVersion(name, latest);
|
||||
success = (file.isFile() && latest.equals(getVersion(name))) || downloadFile(jarFile, filePath);
|
||||
} else {
|
||||
success = file.isFile() || downloadFile(url + version + Objects.requireNonNull(advType).getDownloadURLPart() + version + ".jar", filePath);
|
||||
}
|
||||
break;
|
||||
case "Spigot":
|
||||
case "Craftbukkit":
|
||||
case "MCPCplus":
|
||||
success = file.isFile() || downloadFile(url + name + version + ".jar", filePath);
|
||||
break;
|
||||
case "SpongeVanilla":
|
||||
newestVersion = stringBetween(readFile(Objects.requireNonNull(advType).getVersionURL() + version), advType.getSrcStart(), advType.getSrcEnd());
|
||||
success = file.isFile() || downloadFile(url + newestVersion + advType.getDownloadURLPart() + newestVersion + ".jar", filePath);
|
||||
break;
|
||||
case "Bungee":
|
||||
newestVersion = stringBetween(readFile(Objects.requireNonNull(advType).getVersionURL()), advType.getSrcStart(), advType.getSrcEnd());
|
||||
setVersion(name, newestVersion);
|
||||
success = (file.isFile() && newestVersion.equals(getVersion(name))) || downloadFile(url, filePath);
|
||||
break;
|
||||
default:
|
||||
success = true;
|
||||
}
|
||||
if (!success) {
|
||||
printToGui("Error downloading: " + name + version + ".jar");
|
||||
throw new FileNotFoundException("Error downloading: " + name + version + ".jar");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current version of a type
|
||||
*
|
||||
* @param type The version type
|
||||
* @return The version string
|
||||
*/
|
||||
private static String getVersion(String type) {
|
||||
switch (type) {
|
||||
case "Vanilla":
|
||||
return vanillaVersion;
|
||||
case "Snapshot":
|
||||
return snapshotVersion;
|
||||
case "Bungee":
|
||||
return bungeeVersion;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a server type's last downloaded version.
|
||||
*
|
||||
* @param type The version type
|
||||
* @param version The version string
|
||||
*/
|
||||
private static void setVersion(String type, String version) {
|
||||
if (!type.equals("")) {
|
||||
switch (type) {
|
||||
case "Vanilla":
|
||||
vanillaVersion = version;
|
||||
break;
|
||||
case "Snapshot":
|
||||
snapshotVersion = version;
|
||||
break;
|
||||
case "Bungee":
|
||||
bungeeVersion = version;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package net.knarcraft.minecraftserverlauncher.server;
|
||||
|
||||
/**
|
||||
* A more advanced servertype for particularly tricky jar downloads.
|
||||
*
|
||||
* @author Kristian Knarvik <kristian.knarvik@knett.no>
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class AdvancedServerType extends ServerType {
|
||||
private final String versionURL;
|
||||
private final String downloadURLPart;
|
||||
private final String srcStart;
|
||||
private final String srcEnd;
|
||||
|
||||
AdvancedServerType(String name, String[] versions, String versionURL, String srcStart, String srcEnd, String downloadURL, String downloadURLPart) {
|
||||
super(name, versions, downloadURL);
|
||||
this.srcStart = srcStart;
|
||||
this.srcEnd = srcEnd;
|
||||
this.versionURL = versionURL;
|
||||
this.downloadURLPart = downloadURLPart;
|
||||
}
|
||||
|
||||
public String getVersionURL() {
|
||||
return this.versionURL;
|
||||
}
|
||||
|
||||
public String getDownloadURLPart() {
|
||||
return this.downloadURLPart;
|
||||
}
|
||||
|
||||
public String getSrcStart() {
|
||||
return this.srcStart;
|
||||
}
|
||||
|
||||
public String getSrcEnd() {
|
||||
return this.srcEnd;
|
||||
}
|
||||
}
|
@ -0,0 +1,496 @@
|
||||
package net.knarcraft.minecraftserverlauncher.server;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import net.knarcraft.minecraftserverlauncher.Shared;
|
||||
import net.knarcraft.minecraftserverlauncher.profile.Collection;
|
||||
import net.knarcraft.minecraftserverlauncher.profile.Profile;
|
||||
import net.knarcraft.minecraftserverlauncher.Main;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
/**
|
||||
* Contains all necessary information to create, run and manage a Minecraft server.
|
||||
*
|
||||
* @author Kristian Knarvik <kristian.knarvik@knett.no>
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class Server {
|
||||
/** Available ram sizes. For GUI dropdown */
|
||||
private static final String[] ramList = {
|
||||
"512M", "1G", "2G", "3G", "4G", "5G", "6G", "7G", "8G", "9G", "10G","11G", "12G", "13G", "14G", "15G", "16G"
|
||||
};
|
||||
private static final String jarDir = Main.getAppDir() + File.separator + "files" + File.separator + "Jars" + File.separator;
|
||||
|
||||
private final String name;
|
||||
private String path;
|
||||
private boolean enabled;
|
||||
private final ArrayList<String> playerList;
|
||||
private ServerType type;
|
||||
private String serverVersion;
|
||||
private String maxRam;
|
||||
private Process process;
|
||||
private BufferedWriter writer;
|
||||
private BufferedReader reader;
|
||||
private String vanillaVersion;
|
||||
private String snapshotVersion;
|
||||
private String spongeVanillaVersion;
|
||||
private String bungeeVersion;
|
||||
private boolean started;
|
||||
|
||||
public Server(String name) {
|
||||
this.name = name;
|
||||
this.path = "";
|
||||
this.enabled = false;
|
||||
this.playerList = new ArrayList<>();
|
||||
this.type = null;
|
||||
this.serverVersion = "";
|
||||
this.maxRam = ramList[0];
|
||||
this.process = null;
|
||||
this.writer = null;
|
||||
this.reader = null;
|
||||
this.vanillaVersion = "";
|
||||
this.snapshotVersion = "";
|
||||
this.spongeVanillaVersion = "";
|
||||
this.bungeeVersion = "";
|
||||
}
|
||||
|
||||
public Server(
|
||||
String name,
|
||||
String path,
|
||||
boolean enabled,
|
||||
String typeName,
|
||||
String serverVersion,
|
||||
String maxRam,
|
||||
String vanillaVersion,
|
||||
String snapshotVersion,
|
||||
String spongeVanillaVersion,
|
||||
String bungeeVersion
|
||||
) {
|
||||
this.name = name;
|
||||
this.path = path;
|
||||
this.enabled = enabled;
|
||||
this.type = ServerType.getByName(typeName);
|
||||
this.serverVersion = serverVersion;
|
||||
this.maxRam = maxRam;
|
||||
this.vanillaVersion = vanillaVersion;
|
||||
this.snapshotVersion = snapshotVersion;
|
||||
this.spongeVanillaVersion = spongeVanillaVersion;
|
||||
this.bungeeVersion = bungeeVersion;
|
||||
this.playerList = new ArrayList<>();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public boolean isStarted() {
|
||||
return started;
|
||||
}
|
||||
|
||||
public String getTypeName() {
|
||||
return this.type.getName();
|
||||
}
|
||||
|
||||
public String getServerVersion() {
|
||||
return this.serverVersion;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
public Process getProcess() {
|
||||
return this.process;
|
||||
}
|
||||
|
||||
public String getMaxRam() {
|
||||
return this.maxRam;
|
||||
}
|
||||
|
||||
public static String[] getRamList() {
|
||||
return ramList;
|
||||
}
|
||||
|
||||
public String getVanillaVersion() {
|
||||
return this.vanillaVersion;
|
||||
}
|
||||
|
||||
public String getSnapshotVersion() {
|
||||
return this.snapshotVersion;
|
||||
}
|
||||
|
||||
public String getSpongeVanillaVersion() {
|
||||
return this.spongeVanillaVersion;
|
||||
}
|
||||
|
||||
public String getBungeeVersion() {
|
||||
return this.bungeeVersion;
|
||||
}
|
||||
|
||||
public ArrayList<String> getPlayers() {
|
||||
return this.playerList;
|
||||
}
|
||||
|
||||
public void stopped() {
|
||||
process = null;
|
||||
writer = null;
|
||||
reader = null;
|
||||
started = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A representation of the name of a jarfile.
|
||||
*/
|
||||
private String getType() {
|
||||
if (this.type.getName().equals("Custom")) {
|
||||
return this.serverVersion;
|
||||
} else {
|
||||
return this.type.getName() + this.serverVersion + ".jar";
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void toggle(boolean value) {
|
||||
this.enabled = value;
|
||||
}
|
||||
|
||||
public boolean hasPlayer(String name) {
|
||||
for (String player : this.playerList) {
|
||||
if (player.equals(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void addPlayer(String name) {
|
||||
this.playerList.add(name);
|
||||
Profile.getGUI().addPlayer(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a player with the selected name from the playerlist.
|
||||
*
|
||||
* @param name The name of the player to remove
|
||||
*/
|
||||
public void removePlayer(String name) {
|
||||
for (int i = 0; i < playerList.size(); i++) {
|
||||
if (name.equals(playerList.get(i))) {
|
||||
playerList.remove(i);
|
||||
}
|
||||
}
|
||||
Profile.getGUI().removePlayer(name);
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public void setType(ServerType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void setMaxRam(String ram) {
|
||||
this.maxRam = ram;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the server's server version to a valid version, or ignores the request.
|
||||
*
|
||||
* @param serverVersion Version number.
|
||||
*/
|
||||
public void setServerVersion(String serverVersion) throws IllegalArgumentException {
|
||||
if (this.type.getName().equals("Custom")) {
|
||||
this.serverVersion = serverVersion;
|
||||
} else {
|
||||
String[] versions = this.type.getVersions();
|
||||
for (String version : versions) {
|
||||
if (version.equals(serverVersion)) {
|
||||
this.serverVersion = serverVersion;
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid server version.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to stop all enabled servers.
|
||||
*
|
||||
* @throws IOException If a writer's process is already closed but not null.
|
||||
*/
|
||||
public static void stop() throws IOException {
|
||||
for (Collection collection : Profile.getCurrent().getCollections()) {
|
||||
Server server = collection.getServer();
|
||||
if (server.writer != null) {
|
||||
if (server.type.getName().equals("Bungee")) {
|
||||
server.writer.write("end\n");
|
||||
} else {
|
||||
server.writer.write("stop\n");
|
||||
}
|
||||
server.writer.flush();
|
||||
server.writer = null;
|
||||
server.started = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs all enabled servers with their settings.
|
||||
*/
|
||||
public static void startServers() {
|
||||
Profile.getGUI().setStatus("Starting servers");
|
||||
for (Collection collection : Profile.getCurrent().getCollections()) {
|
||||
if (!collection.getServer().run()) {
|
||||
Profile.getGUI().setStatus("An error occurred. Start aborted");
|
||||
try {
|
||||
Server.stop();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Profile.getGUI().updateRunning(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the Minecraft server.
|
||||
*/
|
||||
private boolean run() {
|
||||
if (this.enabled) {
|
||||
this.started = true;
|
||||
if (!Profile.getCurrent().getDownloadJars()) {
|
||||
try {
|
||||
Profile.getGUI().setStatus("Downloading jar...");
|
||||
this.downloadJar();
|
||||
Profile.getGUI().setStatus("File downloaded");
|
||||
} catch (FileNotFoundException e) {
|
||||
System.out.println(e.getMessage());
|
||||
Profile.getGUI().setStatus("Error: Jar file not found");
|
||||
e.printStackTrace();
|
||||
this.started = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
try {
|
||||
Profile.getGUI().setStatus("Delaying startup");
|
||||
TimeUnit.SECONDS.sleep(Profile.getCurrent().getDelayStartup());
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
this.started = false;
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
ProcessBuilder builder;
|
||||
String serverPath;
|
||||
if (Profile.getCurrent().getDownloadJars() && !type.getName().equals("Custom")) {
|
||||
serverPath = jarDir + this.getType();
|
||||
} else {
|
||||
serverPath = this.path + File.separator + this.getType();
|
||||
}
|
||||
builder = new ProcessBuilder(
|
||||
"java",
|
||||
"-Xmx" + this.maxRam,
|
||||
"-Xms512M",
|
||||
"-Djline.terminal=jline.UnsupportedTerminal",
|
||||
"-Dcom.mojang.eula.agree=true",
|
||||
"-jar",
|
||||
serverPath,
|
||||
"nogui"
|
||||
);
|
||||
builder.directory(new File(this.path));
|
||||
builder.redirectErrorStream(true);
|
||||
this.process = builder.start();
|
||||
this.writer = new BufferedWriter(new OutputStreamWriter(this.process.getOutputStream()));
|
||||
this.reader = new BufferedReader (new InputStreamReader(this.process.getInputStream()));
|
||||
Profile.getGUI().setStatus("Servers are running");
|
||||
this.started = true;
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
Profile.getGUI().setStatus("Could not start server");
|
||||
this.started = false;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
this.started = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all available output from the server process.
|
||||
*
|
||||
* @return The server output
|
||||
* @throws IOException If reading from the reader fails
|
||||
*/
|
||||
public String read() throws IOException {
|
||||
String line;
|
||||
StringBuilder text = new StringBuilder();
|
||||
while (reader.ready() && (line = reader.readLine()) != null) {
|
||||
text.append(line).append("\n");
|
||||
}
|
||||
return text.toString().trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads necessary .jar file for the server.
|
||||
* This is unfortunately hardcoded since there is no golden standard, and we only host some jars ourselves.
|
||||
*
|
||||
* @throws FileNotFoundException if the file was not found and could not be acquired.
|
||||
*/
|
||||
private void downloadJar() throws FileNotFoundException {
|
||||
AdvancedServerType type;
|
||||
File file = new File(this.path + File.separator + this.getType());
|
||||
Path filePath = Paths.get(this.path + File.separator + this.getType());
|
||||
String versionText, newestVersion, url = this.type.getDownloadURL(), name = this.type.getName(), ver = this.serverVersion;
|
||||
switch (this.type.getName()) {
|
||||
case "Custom":
|
||||
if (!file.isFile()) {
|
||||
throw new FileNotFoundException("Specified custom jar was not found.");
|
||||
}
|
||||
break;
|
||||
case "Spigot":
|
||||
case "Craftbukkit":
|
||||
case "MCPCplus":
|
||||
if (!(file.isFile() || Shared.downloadFile(url + name + ver + ".jar", filePath))) {
|
||||
throw new FileNotFoundException("Jar file could not be downloaded.");
|
||||
}
|
||||
break;
|
||||
case "Vanilla":
|
||||
case "Snapshot":
|
||||
type = (AdvancedServerType) this.type;
|
||||
if (this.serverVersion.equals("Latest")) {
|
||||
try {
|
||||
versionText = Shared.readFile(type.getVersionURL());
|
||||
} catch (IOException e) {
|
||||
throw new FileNotFoundException("Version file could not be downloaded.");
|
||||
}
|
||||
JsonObject jsonObject = new JsonParser().parse(versionText).getAsJsonObject();
|
||||
String latest = jsonObject.getAsJsonObject("latest").get("release").getAsString();
|
||||
JsonElement verElem = jsonObject.getAsJsonArray("versions").get(0);
|
||||
String versionFile = verElem.getAsJsonObject().get("url").getAsString();
|
||||
|
||||
try {
|
||||
versionText = Shared.readFile(versionFile);
|
||||
} catch (IOException e) {
|
||||
throw new FileNotFoundException("Version file could not be downloaded.");
|
||||
}
|
||||
|
||||
if (!file.isFile() || !latest.equals(this.getVersion(name))) {
|
||||
this.setVersion(name, latest);
|
||||
|
||||
jsonObject = new JsonParser().parse(versionText).getAsJsonObject();
|
||||
String jarFile = jsonObject.getAsJsonObject("downloads").getAsJsonObject("server").get("url").getAsString();
|
||||
|
||||
if (!Shared.downloadFile(jarFile, filePath)) {
|
||||
throw new FileNotFoundException("Jar file could not be downloaded.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!(file.isFile() || Shared.downloadFile(url + ver + type.getDownloadURLPart() + ver + ".jar", filePath))) {
|
||||
throw new FileNotFoundException("Jar file could not be downloaded.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "SpongeVanilla":
|
||||
type = (AdvancedServerType) this.type;
|
||||
try {
|
||||
versionText = Shared.readFile(type.getVersionURL() + this.serverVersion);
|
||||
} catch (IOException e) {
|
||||
throw new FileNotFoundException("Version file could not be downloaded.");
|
||||
}
|
||||
newestVersion = Shared.stringBetween(versionText, type.getSrcStart(), type.getSrcEnd());
|
||||
if (!file.isFile() || !newestVersion.equals(this.getVersion(name))) {
|
||||
this.setVersion(name, newestVersion);
|
||||
if (!Shared.downloadFile(url + newestVersion + type.getDownloadURLPart() + newestVersion + ".jar", filePath)) {
|
||||
throw new FileNotFoundException("Jar file could not be downloaded.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "Bungee":
|
||||
type = (AdvancedServerType) this.type;
|
||||
try {
|
||||
versionText = Shared.readFile(type.getVersionURL());
|
||||
} catch (IOException e) {
|
||||
throw new FileNotFoundException("Version file could not be downloaded.");
|
||||
}
|
||||
newestVersion = Shared.stringBetween(versionText, type.getSrcStart(), type.getSrcEnd());
|
||||
if (!file.isFile() || !newestVersion.equals(this.getVersion(name))) {
|
||||
this.setVersion(name, newestVersion);
|
||||
if (!Shared.downloadFile(url, filePath)) {
|
||||
throw new FileNotFoundException("Jar file could not be downloaded.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current version of a type
|
||||
*
|
||||
* @param type The version type
|
||||
* @return The version string
|
||||
*/
|
||||
private String getVersion(String type) {
|
||||
switch (type) {
|
||||
case "Vanilla":
|
||||
return this.vanillaVersion;
|
||||
case "Snapshot":
|
||||
return this.snapshotVersion;
|
||||
case "SpongeVanilla":
|
||||
return this.spongeVanillaVersion;
|
||||
case "Bungee":
|
||||
return this.bungeeVersion;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a server type's last downloaded version.
|
||||
*
|
||||
* @param type The version type
|
||||
* @param version The version string
|
||||
*/
|
||||
private void setVersion(String type, String version) {
|
||||
if (!type.equals("")) {
|
||||
switch (type) {
|
||||
case "Vanilla":
|
||||
this.vanillaVersion = version;
|
||||
break;
|
||||
case "Snapshot":
|
||||
this.snapshotVersion = version;
|
||||
break;
|
||||
case "SpongeVanilla":
|
||||
this.spongeVanillaVersion = version;
|
||||
break;
|
||||
case "Bungee":
|
||||
this.bungeeVersion = version;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a command to this server through its writer.
|
||||
*
|
||||
* @param command Command to send to the server
|
||||
* @throws IOException If write fails
|
||||
*/
|
||||
public void sendCommand(String command) throws IOException {
|
||||
if (this.process != null && this.writer != null) {
|
||||
this.writer.write(command + "\n");
|
||||
this.writer.flush();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
package net.knarcraft.minecraftserverlauncher.server;
|
||||
|
||||
import javax.naming.ConfigurationException;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* Contains the bare minimum to be a functional server type.
|
||||
*
|
||||
* @author Kristian Knarvik <kristian.knarvik@knett.no>
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class ServerType {
|
||||
private final String name;
|
||||
private final String[] versions;
|
||||
private final String downloadURL;
|
||||
private static final ArrayList<ServerType> serverTypes = new ArrayList<>();
|
||||
|
||||
ServerType(String name, String[] versions, String downloadURL) {
|
||||
this.name = name;
|
||||
this.versions = versions;
|
||||
this.downloadURL = downloadURL;
|
||||
serverTypes.add(this);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String[] getVersions() {
|
||||
return this.versions;
|
||||
}
|
||||
|
||||
public String getDownloadURL() {
|
||||
return this.downloadURL;
|
||||
}
|
||||
|
||||
public static ArrayList<ServerType> getServerTypes() {
|
||||
return serverTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of all server types' names.
|
||||
*
|
||||
* @return A list of strings
|
||||
*/
|
||||
public static String[] getTypeNames() {
|
||||
ArrayList<ServerType> types = ServerType.getServerTypes();
|
||||
String[] serverTypes = new String[types.size()];
|
||||
for (int i = 0; i < types.size(); i++) {
|
||||
serverTypes[i] = types.get(i).getName();
|
||||
}
|
||||
return serverTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a server type by name.
|
||||
*
|
||||
* @param name Then name of the server type
|
||||
* @return A ServerType
|
||||
*/
|
||||
public static ServerType getByName(String name) {
|
||||
for (ServerType serverType : serverTypes) {
|
||||
if (serverType.getName().equals(name)) {
|
||||
return serverType;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads valid server types and version from a file, and creates their objects.
|
||||
*
|
||||
* @throws ConfigurationException if anything goes wrong.
|
||||
*/
|
||||
public static void loadServerTypes() throws ConfigurationException {
|
||||
if (serverTypes.isEmpty()) {
|
||||
Scanner file;
|
||||
try {
|
||||
file = new Scanner(new File("config/servertypes.csv"));
|
||||
} catch (FileNotFoundException e) {
|
||||
file = new Scanner(ServerType.class.getResourceAsStream("/config/servertypes.csv"));
|
||||
}
|
||||
|
||||
while (file.hasNextLine()) {
|
||||
String[] str = file.nextLine().split(";", -1);
|
||||
int len = str.length;
|
||||
String[] ver;
|
||||
if (str[1].contains(",")) {
|
||||
ver = str[1].split(",", -1);
|
||||
} else {
|
||||
ver = new String[]{str[1]};
|
||||
}
|
||||
switch (len) {
|
||||
case 7:
|
||||
new AdvancedServerType(str[0], ver, str[2], str[3], str[4], str[5], str[6]);
|
||||
break;
|
||||
case 3:
|
||||
new ServerType(str[0], ver, str[2]);
|
||||
break;
|
||||
default:
|
||||
throw new ConfigurationException("Error: Configuration file invalid.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new ConfigurationException("Error: Configuration already loaded.");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
package net.knarcraft.minecraftserverlauncher.userinterface;
|
||||
|
||||
import net.knarcraft.minecraftserverlauncher.profile.Profile;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.DefaultCaret;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static javax.swing.text.DefaultCaret.ALWAYS_UPDATE;
|
||||
|
||||
/**
|
||||
* Acts as a single writable/readable tab
|
||||
* Has a box for user input, and a textArea for server output.
|
||||
*
|
||||
* @author Kristian Knarvik <kristian.knarvik@knett.no>
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class Console implements ActionListener, KeyListener {
|
||||
private final JTextField textInput;
|
||||
private final JTextArea textOutput;
|
||||
private final String name;
|
||||
private final JPanel panel;
|
||||
private final ArrayList<String> commands = new ArrayList<>();
|
||||
private int commandIndex;
|
||||
|
||||
Console(JTabbedPane tab, String name) {
|
||||
this.name = name;
|
||||
panel = new JPanel();
|
||||
tab.addTab(name, null, panel, null);
|
||||
panel.setLayout(new BorderLayout(0, 0));
|
||||
textInput = new JTextField();
|
||||
panel.add(textInput, BorderLayout.SOUTH);
|
||||
textInput.setColumns(10);
|
||||
textInput.addActionListener(this);
|
||||
textOutput = new JTextArea();
|
||||
JScrollPane scroll = new JScrollPane(textOutput);
|
||||
panel.add(scroll, BorderLayout.CENTER);
|
||||
textOutput.setEditable(false);
|
||||
DefaultCaret caret = (DefaultCaret) textOutput.getCaret();
|
||||
caret.setUpdatePolicy(ALWAYS_UPDATE);
|
||||
textOutput.setLineWrap(true);
|
||||
textInput.addKeyListener(this);
|
||||
}
|
||||
|
||||
public JPanel getPanel() {
|
||||
return this.panel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a string to the textArea.
|
||||
*
|
||||
* @param text The text to print
|
||||
*/
|
||||
public void output(String text) {
|
||||
this.textOutput.setText(this.textOutput.getText() + "\n" + text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (e.getSource() == textInput) { //Sends the command from the input to the server with the same name.
|
||||
java.lang.String text = textInput.getText();
|
||||
Profile.getCurrent().sendCommand(this.name, text);
|
||||
commands.add(text);
|
||||
if (commands.size() > 25) {
|
||||
commands.remove(0);
|
||||
}
|
||||
commandIndex = commands.size();
|
||||
textInput.setText("");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_UP) {
|
||||
if (commands.size() > 0 && commandIndex > 0) {
|
||||
textInput.setText(commands.get(--commandIndex));
|
||||
}
|
||||
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
|
||||
if (commands.size() > 0) {
|
||||
if (commandIndex == commands.size() - 1) {
|
||||
commandIndex++;
|
||||
textInput.setText("");
|
||||
} else if (commandIndex >= 0 && commandIndex <= commands.size() - 1) {
|
||||
textInput.setText(commands.get(++commandIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
}
|
||||
}
|
@ -0,0 +1,908 @@
|
||||
package net.knarcraft.minecraftserverlauncher.userinterface;
|
||||
|
||||
import net.knarcraft.minecraftserverlauncher.profile.Collection;
|
||||
import net.knarcraft.minecraftserverlauncher.Main;
|
||||
import net.knarcraft.minecraftserverlauncher.server.Server;
|
||||
import net.knarcraft.minecraftserverlauncher.profile.Profile;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
import java.util.Scanner;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static java.awt.Frame.NORMAL;
|
||||
import static javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE;
|
||||
|
||||
/**
|
||||
* Generates a GUI.
|
||||
*
|
||||
* @author Kristian Knarvik <kristian.knarvik@knett.no>
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class GUI implements ActionListener {
|
||||
|
||||
private JFrame frame;
|
||||
private JTabbedPane tabbedPane;
|
||||
private JTabbedPane serversPane;
|
||||
//Menu
|
||||
private JCheckBoxMenuItem chckbxmntmRunInBackground, chckbxmntmDelayStartup, chckbxmntmDownloadJars; //Options
|
||||
private JMenuItem mntmErrors, mntmSetup, mntmManualUpdate; //Help
|
||||
private JMenuItem mntmRunInBackground, mntmDelayStartup, mntmDownloadJars; //Info/options
|
||||
private JMenuItem mntmAbout, mntmStory; //Info/about
|
||||
//Basic controls
|
||||
private JButton btnStartServer, btnStopServer, addServer, backup, addProfile, delProfile;
|
||||
private JComboBox<String> profiles;
|
||||
private final JLabel lblStatuslabel = new JLabel("Servers are stopped");
|
||||
//Server controls
|
||||
private JComboBox<String> targetServer;
|
||||
private JComboBox<String> targetPlayer;
|
||||
private JButton btnKick, btnBan, btnOp, btnDeop, btnCustomCommand, btnSaveserver, btnReload, btnServerConsoles;
|
||||
private JTextField customCommand;
|
||||
//Text
|
||||
private String setupText;
|
||||
private String runInBackgroundText;
|
||||
private String delayStartupText;
|
||||
private String downloadJarsText;
|
||||
private String aboutText;
|
||||
|
||||
private final ArrayList<String> globalPlayers;
|
||||
private SystemTray tray;
|
||||
private TrayIcon trayIcon;
|
||||
|
||||
/**
|
||||
* Create the application window.
|
||||
*/
|
||||
public GUI() {
|
||||
initialize(440, 170);
|
||||
loadMessages();
|
||||
this.globalPlayers = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the application window with a preferred width and height.
|
||||
*
|
||||
* @param width The preferred width
|
||||
* @param height The preferred height
|
||||
*/
|
||||
public GUI(int width, int height) {
|
||||
initialize(width, height);
|
||||
loadMessages();
|
||||
this.globalPlayers = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pane used for server configurations
|
||||
*
|
||||
* @return A JTabbedPane
|
||||
*/
|
||||
public JTabbedPane getPane() {
|
||||
return this.serversPane;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text of the status label.
|
||||
*
|
||||
* @param text The new text
|
||||
*/
|
||||
public void setStatus(String text) {
|
||||
this.lblStatuslabel.setText(text);
|
||||
try (PrintWriter file = new PrintWriter(new FileWriter(Main.getAppDir() + File.separator + "latestrun.log", true))) {
|
||||
file.println(text);
|
||||
} catch (IOException e ) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a player to the global playerlist, and updates the players combo.
|
||||
*
|
||||
* @param name The name of the player to add
|
||||
*/
|
||||
public void addPlayer(String name) {
|
||||
this.globalPlayers.add(name);
|
||||
this.updatePlayers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a player from the global list of players.
|
||||
*
|
||||
* @param name The name of the player to remove.
|
||||
*/
|
||||
public void removePlayer(String name) {
|
||||
for (int i = 0; i < this.globalPlayers.size(); i++) {
|
||||
if (this.globalPlayers.get(i).equals(name)) {
|
||||
this.globalPlayers.remove(i);
|
||||
}
|
||||
}
|
||||
this.updatePlayers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the profiles combo.
|
||||
*/
|
||||
public void updateProfiles() {
|
||||
this.profiles.removeAllItems();
|
||||
for (Profile profile : Profile.getProfiles()) {
|
||||
this.profiles.addItem(profile.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of the main JFrame
|
||||
*
|
||||
* @return The Dimension of the frame
|
||||
*/
|
||||
public Dimension getSize() {
|
||||
return frame.getContentPane().getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates GUI according to current profile settings.
|
||||
*/
|
||||
public void update() {
|
||||
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().getDownloadJars());
|
||||
this.targetServer.removeAllItems();
|
||||
this.targetServer.addItem("All");
|
||||
for (Collection collection : Profile.getCurrent().getCollections()) {
|
||||
this.targetServer.addItem(collection.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the GUI,
|
||||
*/
|
||||
private void initialize(int width, int height) {
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
} catch (ClassNotFoundException |
|
||||
UnsupportedLookAndFeelException |
|
||||
InstantiationException |
|
||||
IllegalAccessException e
|
||||
) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
frame = new JFrame("Minecraft server launcher");
|
||||
frame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
|
||||
frame.getContentPane().setPreferredSize(new Dimension(width, height));
|
||||
ImageIcon img;
|
||||
try {
|
||||
img = new ImageIcon(ImageIO.read(GUI.class.getResourceAsStream("/files/GUIIcon.png")));
|
||||
} catch (IOException | IllegalArgumentException e) {
|
||||
img = new ImageIcon("files/GUIIcon.png");
|
||||
}
|
||||
frame.setIconImage(img.getImage());
|
||||
|
||||
JMenuBar menuBar = new JMenuBar();
|
||||
frame.setJMenuBar(menuBar);
|
||||
|
||||
JMenu mnOptions = new JMenu("Options");
|
||||
menuBar.add(mnOptions);
|
||||
|
||||
chckbxmntmRunInBackground = new JCheckBoxMenuItem("Run in background on exit");
|
||||
mnOptions.add(chckbxmntmRunInBackground);
|
||||
chckbxmntmRunInBackground.addActionListener(this);
|
||||
|
||||
chckbxmntmDelayStartup = new JCheckBoxMenuItem("Delay Startup");
|
||||
mnOptions.add(chckbxmntmDelayStartup);
|
||||
chckbxmntmDelayStartup.addActionListener(this);
|
||||
|
||||
chckbxmntmDownloadJars = new JCheckBoxMenuItem("Download jars");
|
||||
mnOptions.add(chckbxmntmDownloadJars);
|
||||
chckbxmntmDownloadJars.addActionListener(this);
|
||||
|
||||
JMenu mnHelp = new JMenu("Help");
|
||||
menuBar.add(mnHelp);
|
||||
|
||||
mntmErrors = new JMenuItem("Errors");
|
||||
mnHelp.add(mntmErrors);
|
||||
mntmErrors.addActionListener(this);
|
||||
|
||||
mntmSetup = new JMenuItem("Setup");
|
||||
mnHelp.add(mntmSetup);
|
||||
mntmSetup.addActionListener(this);
|
||||
|
||||
mntmManualUpdate = new JMenuItem("Manual update");
|
||||
mnHelp.add(mntmManualUpdate);
|
||||
mntmManualUpdate.addActionListener(this);
|
||||
|
||||
JMenu mnInfo = new JMenu("Info");
|
||||
menuBar.add(mnInfo);
|
||||
|
||||
JMenu mnOptionsInfo = new JMenu("Options");
|
||||
mnInfo.add(mnOptionsInfo);
|
||||
|
||||
mntmRunInBackground = new JMenuItem("Run in background on exit");
|
||||
mnOptionsInfo.add(mntmRunInBackground);
|
||||
mntmRunInBackground.addActionListener(this);
|
||||
|
||||
mntmDelayStartup = new JMenuItem("Delay Startup");
|
||||
mnOptionsInfo.add(mntmDelayStartup);
|
||||
mntmDelayStartup.addActionListener(this);
|
||||
|
||||
mntmDownloadJars = new JMenuItem("Download jars");
|
||||
mnOptionsInfo.add(mntmDownloadJars);
|
||||
mntmDownloadJars.addActionListener(this);
|
||||
|
||||
JMenu mnAbout = new JMenu("About");
|
||||
mnInfo.add(mnAbout);
|
||||
|
||||
mntmAbout = new JMenuItem("About");
|
||||
mnAbout.add(mntmAbout);
|
||||
mntmAbout.addActionListener(this);
|
||||
|
||||
mntmStory = new JMenuItem("Story");
|
||||
mnAbout.add(mntmStory);
|
||||
mntmStory.addActionListener(this);
|
||||
|
||||
tabbedPane = new JTabbedPane(JTabbedPane.TOP);
|
||||
frame.getContentPane().add(tabbedPane);
|
||||
|
||||
JPanel panelBasic = new JPanel();
|
||||
tabbedPane.addTab("Control panel", null, panelBasic, null);
|
||||
SpringLayout sl_panel = new SpringLayout();
|
||||
panelBasic.setLayout(sl_panel);
|
||||
|
||||
JLabel lblBasicControls = new JLabel("Basic controls");
|
||||
sl_panel.putConstraint(SpringLayout.NORTH, lblBasicControls, 10, SpringLayout.NORTH, panelBasic);
|
||||
panelBasic.add(lblBasicControls);
|
||||
|
||||
btnStartServer = new JButton("Start servers");
|
||||
sl_panel.putConstraint(SpringLayout.WEST, lblBasicControls, 0, SpringLayout.WEST, btnStartServer);
|
||||
sl_panel.putConstraint(SpringLayout.NORTH, btnStartServer, 6, SpringLayout.SOUTH, lblBasicControls);
|
||||
sl_panel.putConstraint(SpringLayout.WEST, btnStartServer, 10, SpringLayout.WEST, panelBasic);
|
||||
panelBasic.add(btnStartServer);
|
||||
btnStartServer.addActionListener(this);
|
||||
|
||||
btnStopServer = new JButton("Stop servers");
|
||||
sl_panel.putConstraint(SpringLayout.NORTH, btnStopServer, 0, SpringLayout.NORTH, btnStartServer);
|
||||
sl_panel.putConstraint(SpringLayout.WEST, btnStopServer, 6, SpringLayout.EAST, btnStartServer);
|
||||
panelBasic.add(btnStopServer);
|
||||
btnStopServer.addActionListener(this);
|
||||
|
||||
JLabel lblProfile = new JLabel("Profile");
|
||||
sl_panel.putConstraint(SpringLayout.NORTH, lblProfile, 6, SpringLayout.SOUTH, btnStartServer);
|
||||
sl_panel.putConstraint(SpringLayout.WEST, lblProfile, 10, SpringLayout.WEST, panelBasic);
|
||||
panelBasic.add(lblProfile);
|
||||
|
||||
addProfile = new JButton("+");
|
||||
sl_panel.putConstraint(SpringLayout.NORTH, addProfile, 6, SpringLayout.SOUTH, lblProfile);
|
||||
sl_panel.putConstraint(SpringLayout.WEST, addProfile, 10, SpringLayout.WEST, panelBasic);
|
||||
panelBasic.add(addProfile);
|
||||
addProfile.addActionListener(this);
|
||||
|
||||
delProfile = new JButton("-");
|
||||
sl_panel.putConstraint(SpringLayout.NORTH, delProfile, 0, SpringLayout.NORTH, addProfile);
|
||||
sl_panel.putConstraint(SpringLayout.WEST, delProfile, 6, SpringLayout.EAST, addProfile);
|
||||
panelBasic.add(delProfile);
|
||||
delProfile.addActionListener(this);
|
||||
|
||||
profiles = new JComboBox<>();
|
||||
sl_panel.putConstraint(SpringLayout.NORTH, profiles, 0, SpringLayout.NORTH, addProfile);
|
||||
sl_panel.putConstraint(SpringLayout.WEST, profiles, 6, SpringLayout.EAST, delProfile);
|
||||
sl_panel.putConstraint(SpringLayout.EAST, profiles, 124, SpringLayout.EAST, delProfile);
|
||||
panelBasic.add(profiles);
|
||||
profiles.addActionListener(this);
|
||||
|
||||
sl_panel.putConstraint(SpringLayout.NORTH, lblStatuslabel, 6, SpringLayout.SOUTH, addProfile);
|
||||
sl_panel.putConstraint(SpringLayout.SOUTH, lblStatuslabel, -10, SpringLayout.SOUTH, panelBasic);
|
||||
sl_panel.putConstraint(SpringLayout.WEST, lblStatuslabel, 10, SpringLayout.WEST, panelBasic);
|
||||
sl_panel.putConstraint(SpringLayout.EAST, lblStatuslabel, -10, SpringLayout.EAST, panelBasic);
|
||||
panelBasic.add(lblStatuslabel);
|
||||
|
||||
addServer = new JButton("Add server");
|
||||
sl_panel.putConstraint(SpringLayout.NORTH, addServer, 0, SpringLayout.NORTH, btnStartServer);
|
||||
sl_panel.putConstraint(SpringLayout.WEST, addServer, 6, SpringLayout.EAST, btnStopServer);
|
||||
panelBasic.add(addServer);
|
||||
addServer.addActionListener(this);
|
||||
|
||||
backup = new JButton("Backup");
|
||||
sl_panel.putConstraint(SpringLayout.NORTH, backup, 0, SpringLayout.NORTH, btnStartServer);
|
||||
sl_panel.putConstraint(SpringLayout.WEST, backup, 6, SpringLayout.EAST, addServer);
|
||||
panelBasic.add(backup);
|
||||
backup.addActionListener(this);
|
||||
|
||||
JPanel controlServers = new JPanel();
|
||||
tabbedPane.addTab("Control servers", null, controlServers, null);
|
||||
SpringLayout sl_panel_1 = new SpringLayout();
|
||||
controlServers.setLayout(sl_panel_1);
|
||||
|
||||
targetServer = new JComboBox<>();
|
||||
sl_panel_1.putConstraint(SpringLayout.NORTH, targetServer, 10, SpringLayout.NORTH, controlServers);
|
||||
controlServers.add(targetServer);
|
||||
targetServer.addActionListener(this);
|
||||
|
||||
targetPlayer = new JComboBox<>();
|
||||
sl_panel_1.putConstraint(SpringLayout.NORTH, targetPlayer, 6, SpringLayout.SOUTH, targetServer);
|
||||
targetPlayer.setEditable(true);
|
||||
controlServers.add(targetPlayer);
|
||||
|
||||
btnKick = new JButton("Kick");
|
||||
sl_panel_1.putConstraint(SpringLayout.NORTH, btnKick, 10, SpringLayout.NORTH, controlServers);
|
||||
sl_panel_1.putConstraint(SpringLayout.WEST, btnKick, 6, SpringLayout.EAST, targetServer);
|
||||
sl_panel_1.putConstraint(SpringLayout.EAST, btnKick, 104, SpringLayout.WEST, btnKick);
|
||||
sl_panel_1.putConstraint(SpringLayout.SOUTH, targetServer, 0, SpringLayout.SOUTH, btnKick);
|
||||
controlServers.add(btnKick);
|
||||
btnKick.addActionListener(this);
|
||||
|
||||
btnBan = new JButton("Ban");
|
||||
sl_panel_1.putConstraint(SpringLayout.NORTH, btnBan, 6, SpringLayout.SOUTH, btnKick);
|
||||
sl_panel_1.putConstraint(SpringLayout.WEST, btnBan, 6, SpringLayout.EAST, targetPlayer);
|
||||
sl_panel_1.putConstraint(SpringLayout.EAST, btnBan, 104, SpringLayout.WEST, btnBan);
|
||||
sl_panel_1.putConstraint(SpringLayout.SOUTH, targetPlayer, 0, SpringLayout.SOUTH, btnBan);
|
||||
controlServers.add(btnBan);
|
||||
btnBan.addActionListener(this);
|
||||
|
||||
btnOp = new JButton("OP");
|
||||
sl_panel_1.putConstraint(SpringLayout.NORTH, btnOp, 10, SpringLayout.NORTH, controlServers);
|
||||
sl_panel_1.putConstraint(SpringLayout.WEST, btnOp, 6, SpringLayout.EAST, btnKick);
|
||||
sl_panel_1.putConstraint(SpringLayout.EAST, btnOp, -10, SpringLayout.EAST, controlServers);
|
||||
controlServers.add(btnOp);
|
||||
btnOp.addActionListener(this);
|
||||
|
||||
btnDeop = new JButton("DEOP");
|
||||
sl_panel_1.putConstraint(SpringLayout.WEST, btnDeop, 6, SpringLayout.EAST, btnBan);
|
||||
sl_panel_1.putConstraint(SpringLayout.NORTH, btnDeop, 5, SpringLayout.SOUTH, btnOp);
|
||||
sl_panel_1.putConstraint(SpringLayout.EAST, btnDeop, -10, SpringLayout.EAST, controlServers);
|
||||
controlServers.add(btnDeop);
|
||||
btnDeop.addActionListener(this);
|
||||
|
||||
JLabel lblTargetServer = new JLabel("Target server");
|
||||
sl_panel_1.putConstraint(SpringLayout.WEST, targetServer, 6, SpringLayout.EAST, lblTargetServer);
|
||||
sl_panel_1.putConstraint(SpringLayout.EAST, targetServer, 121, SpringLayout.EAST, lblTargetServer);
|
||||
sl_panel_1.putConstraint(SpringLayout.NORTH, lblTargetServer, 10, SpringLayout.NORTH, controlServers);
|
||||
sl_panel_1.putConstraint(SpringLayout.SOUTH, lblTargetServer, 0, SpringLayout.SOUTH, targetServer);
|
||||
sl_panel_1.putConstraint(SpringLayout.WEST, lblTargetServer, 10, SpringLayout.WEST, controlServers);
|
||||
controlServers.add(lblTargetServer);
|
||||
|
||||
JLabel lblTargetPlayer = new JLabel("Target player");
|
||||
sl_panel_1.putConstraint(SpringLayout.WEST, targetPlayer, 7, SpringLayout.EAST, lblTargetPlayer);
|
||||
sl_panel_1.putConstraint(SpringLayout.EAST, targetPlayer, 122, SpringLayout.EAST, lblTargetPlayer);
|
||||
sl_panel_1.putConstraint(SpringLayout.NORTH, lblTargetPlayer, 6, SpringLayout.SOUTH, lblTargetServer);
|
||||
sl_panel_1.putConstraint(SpringLayout.SOUTH, lblTargetPlayer, 0, SpringLayout.SOUTH, targetPlayer);
|
||||
sl_panel_1.putConstraint(SpringLayout.WEST, lblTargetPlayer, 0, SpringLayout.WEST, lblTargetServer);
|
||||
controlServers.add(lblTargetPlayer);
|
||||
|
||||
btnCustomCommand = new JButton("Custom command");
|
||||
sl_panel_1.putConstraint(SpringLayout.WEST, btnCustomCommand, 250, SpringLayout.WEST, controlServers);
|
||||
sl_panel_1.putConstraint(SpringLayout.EAST, btnCustomCommand, 0, SpringLayout.EAST, btnOp);
|
||||
controlServers.add(btnCustomCommand);
|
||||
btnCustomCommand.addActionListener(this);
|
||||
frame.getRootPane().setDefaultButton(btnCustomCommand);
|
||||
|
||||
customCommand = new JTextField();
|
||||
sl_panel_1.putConstraint(SpringLayout.WEST, customCommand, 10, SpringLayout.WEST, controlServers);
|
||||
sl_panel_1.putConstraint(SpringLayout.EAST, customCommand, -6, SpringLayout.WEST, btnCustomCommand);
|
||||
sl_panel_1.putConstraint(SpringLayout.NORTH, btnCustomCommand, 0, SpringLayout.NORTH, customCommand);
|
||||
sl_panel_1.putConstraint(SpringLayout.SOUTH, customCommand, 0, SpringLayout.SOUTH, btnCustomCommand);
|
||||
controlServers.add(customCommand);
|
||||
customCommand.setColumns(10);
|
||||
|
||||
btnSaveserver = new JButton("Save server");
|
||||
sl_panel_1.putConstraint(SpringLayout.NORTH, customCommand, 6, SpringLayout.SOUTH, btnSaveserver);
|
||||
sl_panel_1.putConstraint(SpringLayout.NORTH, btnSaveserver, 6, SpringLayout.SOUTH, btnBan);
|
||||
sl_panel_1.putConstraint(SpringLayout.WEST, btnSaveserver, 0, SpringLayout.WEST, btnKick);
|
||||
sl_panel_1.putConstraint(SpringLayout.EAST, btnSaveserver, 104, SpringLayout.WEST, btnKick);
|
||||
sl_panel_1.putConstraint(SpringLayout.EAST, btnSaveserver, 104, SpringLayout.WEST, btnKick);
|
||||
controlServers.add(btnSaveserver);
|
||||
btnSaveserver.addActionListener(this);
|
||||
|
||||
btnReload = new JButton("Reload");
|
||||
sl_panel_1.putConstraint(SpringLayout.NORTH, btnReload, 6, SpringLayout.SOUTH, btnDeop);
|
||||
sl_panel_1.putConstraint(SpringLayout.WEST, btnReload, 0, SpringLayout.WEST, btnDeop);
|
||||
sl_panel_1.putConstraint(SpringLayout.EAST, btnReload, 0, SpringLayout.EAST, btnOp);
|
||||
controlServers.add(btnReload);
|
||||
btnReload.addActionListener(this);
|
||||
|
||||
btnServerConsoles = new JButton("View server consoles");
|
||||
sl_panel_1.putConstraint(SpringLayout.NORTH, btnServerConsoles, 0, SpringLayout.NORTH, btnSaveserver);
|
||||
sl_panel_1.putConstraint(SpringLayout.WEST, btnServerConsoles, 0, SpringLayout.WEST, lblTargetServer);
|
||||
sl_panel_1.putConstraint(SpringLayout.EAST, btnServerConsoles, 0, SpringLayout.EAST, targetServer);
|
||||
controlServers.add(btnServerConsoles);
|
||||
btnServerConsoles.addActionListener(this);
|
||||
|
||||
JPanel panel_2 = new JPanel();
|
||||
tabbedPane.addTab("Servers", null, panel_2, null);
|
||||
SpringLayout sl_panel_2 = new SpringLayout();
|
||||
panel_2.setLayout(sl_panel_2);
|
||||
|
||||
JTabbedPane tabbedPane_1 = new JTabbedPane(JTabbedPane.TOP);
|
||||
sl_panel_2.putConstraint(SpringLayout.NORTH, tabbedPane_1, 0, SpringLayout.NORTH, panel_2);
|
||||
sl_panel_2.putConstraint(SpringLayout.WEST, tabbedPane_1, 0, SpringLayout.WEST, panel_2);
|
||||
sl_panel_2.putConstraint(SpringLayout.SOUTH, tabbedPane_1, 0, SpringLayout.SOUTH, panel_2);
|
||||
sl_panel_2.putConstraint(SpringLayout.EAST, tabbedPane_1, 0, SpringLayout.EAST, panel_2);
|
||||
panel_2.add(tabbedPane_1);
|
||||
|
||||
this.serversPane = tabbedPane_1;
|
||||
tabbedPane_1.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
|
||||
|
||||
frame.validate();
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
tray();
|
||||
updateRunning(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the system tray if available.
|
||||
*/
|
||||
private void tray() {
|
||||
if (SystemTray.isSupported()) {
|
||||
tray = SystemTray.getSystemTray();
|
||||
Image trayImage = Toolkit.getDefaultToolkit().getImage("files/GUIIcon.png");
|
||||
PopupMenu popup = new PopupMenu();
|
||||
trayIcon = new TrayIcon(trayImage, "Minecraft Server Launcher", popup);
|
||||
trayIcon.setImageAutoSize(true);
|
||||
ActionListener exitListener= e -> {
|
||||
stop();
|
||||
try {
|
||||
Profile.getCurrent().save();
|
||||
} catch (FileNotFoundException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
System.exit(0);
|
||||
};
|
||||
|
||||
MenuItem restoreItem = new MenuItem("Restore");
|
||||
popup.add(restoreItem);
|
||||
restoreItem.addActionListener(e -> {
|
||||
frame.setExtendedState(NORMAL);
|
||||
tray.remove(trayIcon);
|
||||
frame.setVisible(true);
|
||||
});
|
||||
MenuItem exitItem = new MenuItem("Exit");
|
||||
exitItem.addActionListener(exitListener);
|
||||
popup.add(exitItem);
|
||||
frame.addWindowStateListener(e -> {
|
||||
if (e.getNewState() == NORMAL) {
|
||||
tray.remove(trayIcon);
|
||||
frame.setVisible(true);
|
||||
}
|
||||
});
|
||||
|
||||
frame.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
if (Profile.getCurrent().getRunInBackground() && SystemTray.isSupported()) {
|
||||
try {
|
||||
tray.add(trayIcon);
|
||||
frame.setVisible(false);
|
||||
} catch (AWTException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
stop();
|
||||
try {
|
||||
Profile.getCurrent().save();
|
||||
} catch (FileNotFoundException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
trayIcon.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if(e.getClickCount() >= 1 && e.getButton() == MouseEvent.BUTTON1){
|
||||
frame.setExtendedState(NORMAL);
|
||||
tray.remove(trayIcon);
|
||||
frame.setVisible(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
frame.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
try {
|
||||
Profile.getCurrent().save();
|
||||
} catch (FileNotFoundException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
stop();
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the gui to the tray,
|
||||
*/
|
||||
public void hide() {
|
||||
frame.setVisible(false);
|
||||
try {
|
||||
tray.add(trayIcon);
|
||||
} catch (AWTException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String selectedServerValue = null, selectedPlayerValue = null;
|
||||
Object selectedServer = targetServer.getSelectedItem();
|
||||
if (selectedServer != null) {
|
||||
selectedServerValue = selectedServer.toString();
|
||||
}
|
||||
Object selectedPlayer = targetPlayer.getSelectedItem();
|
||||
if (selectedPlayer != null) {
|
||||
selectedPlayerValue = selectedPlayer.toString();
|
||||
}
|
||||
if (e.getSource() == chckbxmntmRunInBackground) {
|
||||
background();
|
||||
} else if (e.getSource() == chckbxmntmDelayStartup) {
|
||||
delay();
|
||||
} else if (e.getSource() == chckbxmntmDownloadJars) {
|
||||
downloadJars();
|
||||
} else if (e.getSource() == mntmErrors) {
|
||||
goToURL("https://archive.knarcraft.net/BungeeMinecraftServerLauncherInfo/");
|
||||
} else if (e.getSource() == mntmSetup) {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
setupText,
|
||||
"Setup",
|
||||
JOptionPane.INFORMATION_MESSAGE
|
||||
);
|
||||
} else if (e.getSource() == mntmManualUpdate) {
|
||||
goToURL("https://git.knarcraft.net/EpicKnarvik97/Minecraft-Server-Launcher");
|
||||
} else if (e.getSource() == mntmRunInBackground) {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
runInBackgroundText,
|
||||
"Run in background",
|
||||
JOptionPane.INFORMATION_MESSAGE
|
||||
);
|
||||
} else if (e.getSource() == mntmDelayStartup) {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
delayStartupText,
|
||||
"Delay startup",
|
||||
JOptionPane.INFORMATION_MESSAGE
|
||||
);
|
||||
} else if (e.getSource() == mntmDownloadJars) {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
downloadJarsText,
|
||||
"Download jars",
|
||||
JOptionPane.INFORMATION_MESSAGE
|
||||
);
|
||||
} else if (e.getSource() == mntmAbout) {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
aboutText,
|
||||
"About",
|
||||
JOptionPane.INFORMATION_MESSAGE
|
||||
);
|
||||
} else if (e.getSource() == mntmStory) {
|
||||
goToURL("https://archive.knarcraft.net/BungeeminecraftserverlauncherStory/");
|
||||
} else if (e.getSource() == btnStartServer) {
|
||||
try {
|
||||
Profile.getCurrent().save();
|
||||
} catch (FileNotFoundException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
Executors.newSingleThreadExecutor().execute(Server::startServers);
|
||||
} else if (e.getSource() == btnStopServer) {
|
||||
stop();
|
||||
} else if (e.getSource() == addServer) {
|
||||
String serverName = JOptionPane.showInputDialog("Name of server: ");
|
||||
Profile.getCurrent().addCollection(serverName);
|
||||
this.update();
|
||||
Profile.getCurrent().updateConsoles();
|
||||
} else if (e.getSource() == backup) {
|
||||
backup();
|
||||
} else if (e.getSource() == addProfile) {
|
||||
Profile.addProfile(JOptionPane.showInputDialog("Profile name: "));
|
||||
updateProfiles();
|
||||
} else if (e.getSource() == delProfile) {
|
||||
Object selected = profiles.getSelectedItem();
|
||||
if (selected != null) {
|
||||
Profile.removeProfile(selected.toString());
|
||||
updateProfiles();
|
||||
}
|
||||
} else if (e.getSource() == profiles) {
|
||||
try {
|
||||
changeProfile();
|
||||
} catch (FileNotFoundException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
} else if (e.getSource() == btnKick) {
|
||||
if (selectedServerValue != null && selectedPlayerValue != null) {
|
||||
Profile.getCurrent().sendCommand(selectedServerValue, "kick " + selectedPlayerValue);
|
||||
}
|
||||
} else if (e.getSource() == btnBan) {
|
||||
if (selectedServerValue != null && selectedPlayerValue != null) {
|
||||
Profile.getCurrent().sendCommand(selectedServerValue, "ban " + selectedPlayerValue);
|
||||
}
|
||||
} else if (e.getSource() == btnOp) {
|
||||
if (selectedServerValue != null && selectedPlayerValue != null) {
|
||||
Profile.getCurrent().sendCommand(selectedServerValue, "op " + selectedPlayerValue);
|
||||
}
|
||||
} else if (e.getSource() == btnDeop) {
|
||||
if (selectedServerValue != null && selectedPlayerValue != null) {
|
||||
Profile.getCurrent().sendCommand(selectedServerValue, "deop " + selectedPlayerValue);
|
||||
}
|
||||
} else if (e.getSource() == btnCustomCommand) {
|
||||
if (selectedServerValue != null) {
|
||||
Profile.getCurrent().sendCommand(selectedServerValue, customCommand.getText());
|
||||
customCommand.setText("");
|
||||
}
|
||||
} else if (e.getSource() == btnSaveserver) {
|
||||
if (selectedServerValue != null) {
|
||||
Profile.getCurrent().sendCommand(selectedServerValue, "save-all");
|
||||
}
|
||||
} else if (e.getSource() == btnReload) {
|
||||
if (selectedServerValue != null) {
|
||||
Profile.getCurrent().sendCommand(selectedServerValue, "reload");
|
||||
}
|
||||
} else if (e.getSource() == btnServerConsoles) {
|
||||
ServerConsoles.show();
|
||||
} else if (e.getSource() == targetServer) {
|
||||
updatePlayers();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the GUI components to block a user from doing illegal actions.
|
||||
*
|
||||
* @param running Are the servers currently running?
|
||||
*/
|
||||
public void updateRunning(boolean running) {
|
||||
boolean stopped = !running; //Most gui is only enabled when the server is stopped rather than running.
|
||||
profiles.setEnabled(stopped);
|
||||
addProfile.setEnabled(stopped);
|
||||
delProfile.setEnabled(stopped);
|
||||
btnStartServer.setEnabled(stopped);
|
||||
addServer.setEnabled(stopped);
|
||||
tabbedPane.setEnabledAt(2, stopped);
|
||||
btnStopServer.setEnabled(running);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the previous profile and loads data from the new profile.
|
||||
*/
|
||||
private void changeProfile() throws FileNotFoundException {
|
||||
Profile.getCurrent().save();
|
||||
Object current = this.profiles.getSelectedItem();
|
||||
if (current != null) {
|
||||
Profile.setCurrent(current.toString());
|
||||
}
|
||||
this.update();
|
||||
Profile.getCurrent().updateConsoles();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops all servers
|
||||
*/
|
||||
private void stop() {
|
||||
try {
|
||||
setStatus("Servers are stopping...");
|
||||
Server.stop();
|
||||
} catch (IOException e1) {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"Could not stop server.",
|
||||
"Error",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the user for a delay if checked, and sets the value to the current profile.
|
||||
*/
|
||||
private void delay() {
|
||||
Object selected = profiles.getSelectedItem();
|
||||
if (selected != null) {
|
||||
Profile profile = Profile.getProfile(selected.toString());
|
||||
if (chckbxmntmDelayStartup.isSelected()) {
|
||||
Objects.requireNonNull(profile).setDelayStartup(
|
||||
Integer.parseInt(JOptionPane.showInputDialog("Seconds to delay: "))
|
||||
);
|
||||
} else {
|
||||
Objects.requireNonNull(profile).setDelayStartup(0);
|
||||
}
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"No profile selected",
|
||||
"Error",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the runInBackground setting to the current profile.
|
||||
*/
|
||||
private void background() {
|
||||
Object selected = profiles.getSelectedItem();
|
||||
if (selected != null) {
|
||||
Profile profile = Profile.getProfile(selected.toString());
|
||||
Objects.requireNonNull(profile).setRunInBackground(chckbxmntmRunInBackground.isSelected());
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"No profile selected",
|
||||
"Error",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the downloadJars setting to the current profile.
|
||||
*/
|
||||
private void downloadJars() {
|
||||
Object selected = profiles.getSelectedItem();
|
||||
if (selected != null) {
|
||||
Profile profile = Profile.getProfile(selected.toString());
|
||||
Objects.requireNonNull(profile).setDownloadJars(chckbxmntmDownloadJars.isSelected());
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"No profile selected",
|
||||
"Error",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
copyFolder(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,
|
||||
*/
|
||||
private void updatePlayers() {
|
||||
String selectedServerValue;
|
||||
Object selectedServer = targetServer.getSelectedItem();
|
||||
if (selectedServer != null) {
|
||||
targetPlayer.removeAllItems();
|
||||
selectedServerValue = selectedServer.toString();
|
||||
if (selectedServerValue.equals("All")) {
|
||||
for (String player : this.globalPlayers) {
|
||||
targetPlayer.addItem(player);
|
||||
}
|
||||
} else {
|
||||
for (String player : Profile.getCurrent().getCollection(selectedServerValue).getServer().getPlayers()) {
|
||||
targetPlayer.addItem(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens an url in the user's default application.
|
||||
*
|
||||
* @param url URL to open
|
||||
*/
|
||||
private void goToURL(String url) {
|
||||
java.awt.Desktop desktop = java.awt.Desktop.getDesktop();
|
||||
try {
|
||||
desktop.browse(new URI(url));
|
||||
} catch (URISyntaxException | IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads popup messages from a text file.
|
||||
*/
|
||||
private void loadMessages() {
|
||||
Scanner file;
|
||||
try {
|
||||
file = new Scanner(new File("config/menumsg.csv"));
|
||||
} catch (FileNotFoundException e) {
|
||||
file = new Scanner(GUI.class.getResourceAsStream("/config/menumsg.csv"));
|
||||
}
|
||||
while (file.hasNextLine()) {
|
||||
String[] line = file.nextLine().split("=");
|
||||
String content = line[1].replaceAll("_BREAK_", System.getProperty("line.separator"));
|
||||
switch (line[0]) {
|
||||
case "setup":
|
||||
setupText = content;
|
||||
break;
|
||||
case "runinbk":
|
||||
runInBackgroundText = content;
|
||||
break;
|
||||
case "delaystartup":
|
||||
delayStartupText = content;
|
||||
break;
|
||||
case "downloadjars":
|
||||
downloadJarsText = content;
|
||||
break;
|
||||
case "about":
|
||||
aboutText = content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursivly copies a folder to another location
|
||||
*
|
||||
* @param src The folder to copy
|
||||
* @param dest Target destination
|
||||
* @throws IOException If we can't start a file stream
|
||||
*/
|
||||
private void copyFolder(File src, File dest) throws IOException{
|
||||
if (!src.isDirectory()) {
|
||||
InputStream in = new FileInputStream(src);
|
||||
OutputStream out = new FileOutputStream(dest);
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
while ((length = in.read(buffer)) > 0){
|
||||
out.write(buffer, 0, length);
|
||||
}
|
||||
in.close();
|
||||
out.close();
|
||||
this.setStatus("Copied file " + src);
|
||||
} else {
|
||||
if(!dest.exists()){
|
||||
if (dest.mkdir()) {
|
||||
this.setStatus("Copied directory " + src);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
String files[] = src.list();
|
||||
if (files != null) {
|
||||
for (String file : files) {
|
||||
File srcFile = new File(src, file);
|
||||
File destFile = new File(dest, file);
|
||||
copyFolder(srcFile, destFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package net.knarcraft.minecraftserverlauncher.userinterface;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JTabbedPane;
|
||||
import java.awt.BorderLayout;
|
||||
|
||||
/**
|
||||
* A parent window for server consoles.
|
||||
* Should be toggled with the "View server consoles" button.
|
||||
* Keeps track of all consoles.
|
||||
*
|
||||
* @author Kristian Knarvik <kristian.knarvik@knett.no>
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class ServerConsoles {
|
||||
private static JFrame frame;
|
||||
private static JTabbedPane consolesTab;
|
||||
|
||||
public ServerConsoles() {
|
||||
frame = new JFrame();
|
||||
frame.setBounds(100, 100, 450, 300);
|
||||
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
|
||||
consolesTab = new JTabbedPane(JTabbedPane.TOP);
|
||||
frame.getContentPane().add(consolesTab, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
public static Console addTab(String name) {
|
||||
return new Console(consolesTab, name);
|
||||
}
|
||||
|
||||
public static void show() {
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
public static JTabbedPane getTab() {
|
||||
return consolesTab;
|
||||
}
|
||||
}
|
@ -0,0 +1,243 @@
|
||||
package net.knarcraft.minecraftserverlauncher.userinterface;
|
||||
|
||||
import net.knarcraft.minecraftserverlauncher.profile.Profile;
|
||||
import net.knarcraft.minecraftserverlauncher.server.Server;
|
||||
import net.knarcraft.minecraftserverlauncher.server.ServerType;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
/**
|
||||
* Contains all buttons for configuring a server.
|
||||
* Does some visual stuff by itself, but otherwise reads user inputs.
|
||||
*
|
||||
* @author Kristian Knarvik <kristian.knarvik@knett.no>
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class ServerTab implements ActionListener {
|
||||
private final JComboBox<String> serverTypes, serverVersions, maxRam;
|
||||
private final JCheckBox chckbxEnabled;
|
||||
private final JButton btnRemoveServer, btnBrowse;
|
||||
private final JTextField directory;
|
||||
private final JPanel panel;
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Updates the server tab components according to the received parameters.
|
||||
*
|
||||
* @param path The new path
|
||||
* @param enabled The enabled status of the server
|
||||
* @param typeName The name of the selected server type
|
||||
* @param serverVersion The version of the server
|
||||
* @param maxRam The max usable ram for the server
|
||||
*/
|
||||
public void setData(String path, boolean enabled, String typeName, String serverVersion, String maxRam) {
|
||||
this.directory.setText(path);
|
||||
this.chckbxEnabled.setSelected(enabled);
|
||||
this.serverTypes.setSelectedItem(typeName);
|
||||
this.serverTypes();
|
||||
this.serverVersions.setSelectedItem(serverVersion);
|
||||
this.maxRam.setSelectedItem(maxRam);
|
||||
}
|
||||
|
||||
public ServerTab(String name) {
|
||||
this.name = name;
|
||||
panel = new JPanel();
|
||||
Profile.getGUI().getPane().addTab(name, null, panel, null);
|
||||
SpringLayout sl_panel_3 = new SpringLayout();
|
||||
panel.setLayout(sl_panel_3);
|
||||
|
||||
JLabel lblServerType = new JLabel("Server type");
|
||||
sl_panel_3.putConstraint(SpringLayout.WEST, lblServerType, 10, SpringLayout.WEST, panel);
|
||||
panel.add(lblServerType);
|
||||
|
||||
JLabel lblServerVersion = new JLabel("Server version");
|
||||
sl_panel_3.putConstraint(SpringLayout.NORTH, lblServerVersion, 6, SpringLayout.SOUTH, lblServerType);
|
||||
sl_panel_3.putConstraint(SpringLayout.WEST, lblServerVersion, 10, SpringLayout.WEST, panel);
|
||||
sl_panel_3.putConstraint(SpringLayout.SOUTH, lblServerVersion, 26, SpringLayout.SOUTH, lblServerType);
|
||||
panel.add(lblServerVersion);
|
||||
|
||||
serverTypes = new JComboBox<>(ServerType.getTypeNames());
|
||||
sl_panel_3.putConstraint(SpringLayout.NORTH, serverTypes, 10, SpringLayout.NORTH, panel);
|
||||
sl_panel_3.putConstraint(SpringLayout.WEST, serverTypes, 5, SpringLayout.EAST, lblServerVersion);
|
||||
sl_panel_3.putConstraint(SpringLayout.EAST, serverTypes, 154, SpringLayout.WEST, serverTypes);
|
||||
sl_panel_3.putConstraint(SpringLayout.NORTH, lblServerType, 0, SpringLayout.NORTH, serverTypes);
|
||||
sl_panel_3.putConstraint(SpringLayout.SOUTH, lblServerType, 0, SpringLayout.SOUTH, serverTypes);
|
||||
panel.add(serverTypes);
|
||||
serverTypes.addActionListener(this);
|
||||
|
||||
serverVersions = new JComboBox<>(ServerType.getServerTypes().get(0).getVersions());
|
||||
sl_panel_3.putConstraint(SpringLayout.NORTH, serverVersions, 6, SpringLayout.SOUTH, serverTypes);
|
||||
sl_panel_3.putConstraint(SpringLayout.EAST, serverVersions, 0, SpringLayout.EAST, serverTypes);
|
||||
sl_panel_3.putConstraint(SpringLayout.WEST, serverVersions, 6, SpringLayout.EAST, lblServerVersion);
|
||||
sl_panel_3.putConstraint(SpringLayout.NORTH, lblServerVersion, 0, SpringLayout.NORTH, serverVersions);
|
||||
sl_panel_3.putConstraint(SpringLayout.SOUTH, lblServerVersion, 0, SpringLayout.SOUTH, serverVersions);
|
||||
panel.add(serverVersions);
|
||||
serverVersions.addActionListener(this);
|
||||
|
||||
JLabel lblMaxRam = new JLabel("Max ram");
|
||||
sl_panel_3.putConstraint(SpringLayout.NORTH, lblMaxRam, 0, SpringLayout.NORTH, serverTypes);
|
||||
sl_panel_3.putConstraint(SpringLayout.SOUTH, lblMaxRam, 0, SpringLayout.SOUTH, serverTypes);
|
||||
sl_panel_3.putConstraint(SpringLayout.WEST, lblMaxRam, 6, SpringLayout.EAST, serverTypes);
|
||||
panel.add(lblMaxRam);
|
||||
|
||||
maxRam = new JComboBox<>(Server.getRamList());
|
||||
sl_panel_3.putConstraint(SpringLayout.NORTH, maxRam, 0, SpringLayout.NORTH, serverTypes);
|
||||
sl_panel_3.putConstraint(SpringLayout.WEST, maxRam, 6, SpringLayout.EAST, lblMaxRam);
|
||||
sl_panel_3.putConstraint(SpringLayout.EAST, maxRam, -10, SpringLayout.EAST, panel);
|
||||
panel.add(maxRam);
|
||||
maxRam.addActionListener(this);
|
||||
|
||||
chckbxEnabled = new JCheckBox("Enabled");
|
||||
sl_panel_3.putConstraint(SpringLayout.WEST, chckbxEnabled, 10, SpringLayout.WEST, panel);
|
||||
panel.add(chckbxEnabled);
|
||||
chckbxEnabled.addActionListener(this);
|
||||
|
||||
btnRemoveServer = new JButton("Remove server");
|
||||
sl_panel_3.putConstraint(SpringLayout.NORTH, btnRemoveServer, 0, SpringLayout.NORTH, serverVersions);
|
||||
sl_panel_3.putConstraint(SpringLayout.SOUTH, btnRemoveServer, 0, SpringLayout.SOUTH, serverVersions);
|
||||
sl_panel_3.putConstraint(SpringLayout.WEST, btnRemoveServer, 6, SpringLayout.EAST, serverVersions);
|
||||
sl_panel_3.putConstraint(SpringLayout.EAST, btnRemoveServer, -10, SpringLayout.EAST, panel);
|
||||
panel.add(btnRemoveServer);
|
||||
btnRemoveServer.addActionListener(this);
|
||||
|
||||
JLabel lblDirectory = new JLabel("Directory");
|
||||
sl_panel_3.putConstraint(SpringLayout.WEST, lblDirectory, 6, SpringLayout.EAST, chckbxEnabled);
|
||||
panel.add(lblDirectory);
|
||||
|
||||
directory = new JTextField();
|
||||
sl_panel_3.putConstraint(SpringLayout.WEST, directory, 6, SpringLayout.EAST, lblDirectory);
|
||||
sl_panel_3.putConstraint(SpringLayout.SOUTH, lblDirectory, 0, SpringLayout.SOUTH, directory);
|
||||
sl_panel_3.putConstraint(SpringLayout.NORTH, lblDirectory, 0, SpringLayout.NORTH, directory);
|
||||
sl_panel_3.putConstraint(SpringLayout.NORTH, chckbxEnabled, 0, SpringLayout.NORTH, directory);
|
||||
sl_panel_3.putConstraint(SpringLayout.SOUTH, chckbxEnabled, 0, SpringLayout.SOUTH, directory);
|
||||
panel.add(directory);
|
||||
directory.setColumns(10);
|
||||
directory.addActionListener(this);
|
||||
|
||||
btnBrowse = new JButton("Browse");
|
||||
sl_panel_3.putConstraint(SpringLayout.EAST, directory, -6, SpringLayout.WEST, btnBrowse);
|
||||
sl_panel_3.putConstraint(SpringLayout.NORTH, btnBrowse, 3, SpringLayout.SOUTH, btnRemoveServer);
|
||||
sl_panel_3.putConstraint(SpringLayout.EAST, btnBrowse, -10, SpringLayout.EAST, panel);
|
||||
sl_panel_3.putConstraint(SpringLayout.SOUTH, directory, 0, SpringLayout.SOUTH, btnBrowse);
|
||||
sl_panel_3.putConstraint(SpringLayout.NORTH, directory, 0, SpringLayout.NORTH, btnBrowse);
|
||||
panel.add(btnBrowse);
|
||||
btnBrowse.addActionListener(this);
|
||||
}
|
||||
|
||||
public JPanel getPanel() {
|
||||
return this.panel;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return this.directory.getText();
|
||||
}
|
||||
|
||||
public String getMaxRam() {
|
||||
Object selected = this.maxRam.getSelectedItem();
|
||||
if (selected != null) {
|
||||
return selected.toString();
|
||||
} else {
|
||||
return "512M";
|
||||
}
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
Object selected = this.serverTypes.getSelectedItem();
|
||||
if (selected != null) {
|
||||
return selected.toString();
|
||||
} else {
|
||||
return "Vanilla";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the selected version from the serverVersion combo
|
||||
*
|
||||
* @return The combo value, or defaults to "Latest" on null
|
||||
*/
|
||||
public String getVersion() {
|
||||
Object selected = this.serverVersions.getSelectedItem();
|
||||
if (selected != null) {
|
||||
return selected.toString();
|
||||
} else {
|
||||
return "Latest";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the server is enabled
|
||||
*
|
||||
* @return True if the checkbox is checked. False otherwise.
|
||||
*/
|
||||
public boolean enabled() {
|
||||
return this.chckbxEnabled.isSelected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (e.getSource() == btnRemoveServer) {
|
||||
remove();
|
||||
} else if (e.getSource() == btnBrowse) {
|
||||
browse();
|
||||
} else if (e.getSource() == serverTypes) {
|
||||
serverTypes();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the collection containing this ServerTab, and updates everything necessary.
|
||||
*/
|
||||
private void remove() {
|
||||
Profile.getCurrent().removeCollection(this.name);
|
||||
Profile.getGUI().update();
|
||||
Profile.getCurrent().updateConsoles();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the user for the server folder.
|
||||
* Sets the directory input's value if successful.
|
||||
*/
|
||||
private void browse() {
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
chooser.setCurrentDirectory(new java.io.File("/"));
|
||||
chooser.setDialogTitle("Server folder");
|
||||
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
chooser.setAcceptAllFileFilterUsed(false);
|
||||
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
|
||||
directory.setText(chooser.getSelectedFile().toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the versions combo according to the value of the server type combo.
|
||||
*/
|
||||
private void serverTypes() {
|
||||
serverVersions.removeAllItems();
|
||||
String selectedserverTypes = null;
|
||||
Object selectedType = serverTypes.getSelectedItem();
|
||||
if (selectedType != null) {
|
||||
selectedserverTypes = selectedType.toString();
|
||||
}
|
||||
if (selectedserverTypes != null) {
|
||||
if (selectedserverTypes.equals("Custom")) {
|
||||
serverVersions.setEditable(true);
|
||||
} else {
|
||||
serverVersions.setEditable(false);
|
||||
ServerType current = null;
|
||||
for (ServerType servertype : ServerType.getServerTypes()) {
|
||||
if (servertype.getName().equals(selectedserverTypes)) {
|
||||
current = servertype;
|
||||
}
|
||||
}
|
||||
if (current != null) {
|
||||
for (String version : current.getVersions()) {
|
||||
serverVersions.addItem(version);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user