Skip to content

Commit

Permalink
Changed Start System, Added custom start command
Browse files Browse the repository at this point in the history
  • Loading branch information
notTamion committed Sep 8, 2023
1 parent 2703d5c commit 3324056
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 85 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>de.tamion</groupId>
<artifactId>MinecraftServerCLI</artifactId>
<version>1.1.0</version>
<version>1.2.0</version>

<properties>
<maven.compiler.source>17</maven.compiler.source>
Expand Down
72 changes: 39 additions & 33 deletions src/main/java/de/tamion/InstallCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
import picocli.CommandLine;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;

Expand All @@ -18,16 +19,17 @@ public class InstallCommand implements Runnable {
@CommandLine.Option(names = {"-p", "--project"}, description = "Project you want to download") String project = "paper";
@CommandLine.Parameters(index = "0", description = "Version you want to install", arity = "0..1") String version = "latest";
@CommandLine.Option(names = {"-b", "--build"}, description = "Build of Version") String build = "latest";
@CommandLine.Option(names = {"-sc", "--startcommand"}, description = "The Command used to start the server, replaces %memory and %nogui with there respective values") String startCommand = "java -Xms%memory -Xmx%memory -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -jar ./server.jar %nogui";
@CommandLine.Option(names = {"-ns", "--nostart"}, description = "Don't start the server after installing") boolean nostart;
@CommandLine.Option(names = {"-ng", "--nogui"}, description = "Start the server without a gui") boolean nogui;
@CommandLine.Option(names = {"-m", "--memory"}, description = "How much RAM you want to give the server") String memory = "2G";

@Override
public void run() {
project = project.toLowerCase();
Properties props = new Properties();
try {
Properties props = new Properties();
if(version.equalsIgnoreCase("latest")) {
if (version.equalsIgnoreCase("latest")) {
String[] versions;
switch (project) {
case "fabric":
Expand All @@ -45,7 +47,7 @@ public void run() {
}
version = versions[versions.length - 1].replaceAll("\"", "");
}
if(build.equalsIgnoreCase("latest")) {
if (build.equalsIgnoreCase("latest")) {
switch (project) {
case "fabric":
JsonNode json = new ObjectMapper().readTree(new URL("https://meta.fabricmc.net/v2/versions/loader"));
Expand All @@ -62,11 +64,10 @@ public void run() {
default:
String[] builds = new ObjectMapper().readTree(new URL("https://api.papermc.io/v2/projects/" + project + "/versions/" + version)).get("builds").toString().replaceAll("\\[", "").replaceAll("]", "").split(",");
build = builds[builds.length - 1];
break;
}
props.setProperty("AutoUpdater", "true");
props.setProperty("autoupdater", "true");
} else {
props.setProperty("AutoUpdater", "false");
props.setProperty("autoupdater", "false");
}
System.out.println("Downloading " + project + " version " + version + " build #" + build + "...");
switch (project) {
Expand All @@ -83,40 +84,45 @@ public void run() {
default:
FileUtils.copyURLToFile(new URL("https://api.papermc.io/v2/projects/" + project + "/versions/" + version + "/builds/" + build + "/downloads/" + project + "-" + version + "-" + build + ".jar"), new File(directory + "/server.jar"));
}
System.out.println("Downloaded Server");
String noguis = "";
if(nogui) {
noguis = "--nogui";
}
} catch (MalformedURLException e) {
System.out.println("Please send exception to developer on Discord: tamion\n");
e.printStackTrace();
} catch (IOException e) {
System.out.println("Failed to find " + project + " version " + version + " build " + build);
}
System.out.println("Downloaded Server");
try {
if (System.getProperty("os.name").toLowerCase().contains("win")) {
FileUtils.writeStringToFile(new File(directory + "/start.bat"), "mcs start " + noguis);
FileUtils.writeStringToFile(new File(directory + "/start.bat"), "mcs start");
} else {
FileUtils.writeStringToFile(new File(directory + "/start.sh"), "mcs start " + noguis);
FileUtils.writeStringToFile(new File(directory + "/start.sh"), "mcs start");
}
System.out.println("Created Start Script");
props.setProperty("project", project);
props.setProperty("version", version);
props.setProperty("build", build);
props.setProperty("memory", memory);
} catch (IOException e) {
System.out.println("Unable to create Start Script");
}
System.out.println("Created Start Script");
props.setProperty("project", project);
props.setProperty("version", version);
props.setProperty("build", build);
props.setProperty("nogui", String.valueOf(nogui));
props.setProperty("memory", memory);
props.setProperty("startcommand", startCommand);
try {
props.store(new FileWriter(directory + "/mcscli.properties"), "MinecraftServerCLI settings");
System.out.println("Created Properties File");
} catch (IOException e) {
System.out.println("Unable to create Properties File");
}
System.out.println("Created Properties File");
try {
if(project.equals("paper") || project.equals("purpur") || project.equals("magma") || project.equals("fabric") || project.equals("folia")) {
FileUtils.writeStringToFile(new File(directory + "/eula.txt"), "eula=true");
System.out.println("Accepted Eula");
}
if(nostart) {
return;
}
System.out.println("Starting server");
new ProcessBuilder("java", "-Xms" + memory, "-Xmx" + memory, "-jar", "./server.jar", noguis)
.directory(new File(directory))
.inheritIO()
.start()
.waitFor();
} catch(FileNotFoundException e) {
System.out.println("No downloadable server software found for " + project + " version " + version + " build " + build);
} catch (Exception e) {
e.printStackTrace();
} catch (IOException e) {
System.out.println("Unable to accept Eula");
}
if(!nostart) {
CommandLine.run(new StartCommand(), "-d", directory);
}
}
}
2 changes: 1 addition & 1 deletion src/main/java/de/tamion/MinecraftServerCLICommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import picocli.CommandLine;

@CommandLine.Command(name = "mcs", version = "1.1.0", description = "MinecraftServerCLI", mixinStandardHelpOptions = true, subcommands = {InstallCommand.class, StartCommand.class, ProjectsCommand.class, VersionsCommand.class, BuildsCommand.class})
@CommandLine.Command(name = "mcs", version = "1.2.0", description = "MinecraftServerCLI", mixinStandardHelpOptions = true, subcommands = {InstallCommand.class, StartCommand.class, ProjectsCommand.class, VersionsCommand.class, BuildsCommand.class})
public class MinecraftServerCLICommand implements Runnable {
public static void main(String[] args) {
CommandLine.run(new MinecraftServerCLICommand(), args);
Expand Down
125 changes: 75 additions & 50 deletions src/main/java/de/tamion/StartCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,89 +6,114 @@
import picocli.CommandLine;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;

@CommandLine.Command(name = "start", description = "Start Server", mixinStandardHelpOptions = true)
public class StartCommand implements Runnable {

@CommandLine.Option(names = {"-d", "--directory"}, description = "Server Directory") String directory = ".";
@CommandLine.Option(names = {"-m", "--memory"}, description = "How much RAM you want to give the server") String memory = "default";
@CommandLine.Option(names = {"-ng", "--nogui"}, description = "Start the server without a gui") boolean nogui;
@CommandLine.Option(names = {"-sc", "--startcommand"}, description = "The Command used to start the server, replaces %memory and %nogui with there respective values") String startCommand;
@CommandLine.Option(names = {"-m", "--memory"}, description = "How much RAM you want to give the server") String memory;
@CommandLine.Option(names = {"-ng", "--nogui"}, description = "Start the server without a gui") Boolean nogui;
@Override
public void run() {
try {
String noguis = "";
if(new File(directory + "/mcscli.properties").exists()) {
if(new File(directory + "/mcscli.properties").exists()) {
try {
Properties props = new Properties();
props.load(new FileReader(directory + "/mcscli.properties"));
String project = props.getProperty("project");
String version = props.getProperty("version");
String currentbuild = props.getProperty("build");
if(memory.equalsIgnoreCase("default")) {
if(startCommand == null) {
startCommand = props.getProperty("startcommand");
}
if (memory == null) {
memory = props.getProperty("memory");
}
if(nogui) {
noguis = "--nogui";
if (nogui == null) {
nogui = Boolean.parseBoolean(props.getProperty("nogui"));
}
if (props.getProperty("AutoUpdater").equals("true")) {
String latestbuild;
switch (project) {
case "fabric":
JsonNode json = new ObjectMapper().readTree(new URL("https://meta.fabricmc.net/v2/versions/loader"));
latestbuild = json.iterator().next().get("version").asText();
json = new ObjectMapper().readTree(new URL("https://meta.fabricmc.net/v2/versions/installer"));
latestbuild = latestbuild + ":" + json.iterator().next().get("version").asText();
break;
case "magma":
latestbuild = new ObjectMapper().readTree(new URL("https://api.magmafoundation.org/api/v2/" + version + "/latest")).get("name").asText();
break;
case "purpur":
latestbuild = new ObjectMapper().readTree(new URL("https://api.purpurmc.org/v2/" + project + "/" + version + "/latest")).get("build").asText();
break;
default:
String[] builds = new ObjectMapper().readTree(new URL("https://api.papermc.io/v2/projects/" + project + "/versions/" + version)).get("builds").toString().replaceAll("\\[", "").replaceAll("]", "").split(",");
latestbuild = builds[builds.length - 1];
break;
}
if (!latestbuild.equals(currentbuild)) {
System.out.println("Downloading " + project + " version " + version + " build #" + latestbuild + "...");
if (props.getProperty("autoupdater").equals("true")) {
try {
String latestbuild = null;
switch (project) {
case "fabric":
String[] builds = latestbuild.split(":");
FileUtils.copyURLToFile(new URL("https://meta.fabricmc.net/v2/versions/loader/" + version + "/" + builds[0] + "/" + builds[1] + "/server/jar"), new File(directory + "/server.jar"));
JsonNode json = new ObjectMapper().readTree(new URL("https://meta.fabricmc.net/v2/versions/loader"));
latestbuild = json.iterator().next().get("version").asText();
json = new ObjectMapper().readTree(new URL("https://meta.fabricmc.net/v2/versions/installer"));
latestbuild = latestbuild + ":" + json.iterator().next().get("version").asText();
break;
case "magma":
FileUtils.copyURLToFile(new URL("https://api.magmafoundation.org/api/v2/" + version + "/latest/" + latestbuild + "/download"), new File(directory + "/server.jar"));
latestbuild = new ObjectMapper().readTree(new URL("https://api.magmafoundation.org/api/v2/" + version + "/latest")).get("name").asText();
break;
case "purpur":
FileUtils.copyURLToFile(new URL("https://api.purpurmc.org/v2/" + project + "/" + version + "/" + latestbuild + "/download"), new File(directory + "/server.jar"));
latestbuild = new ObjectMapper().readTree(new URL("https://api.purpurmc.org/v2/" + project + "/" + version + "/latest")).get("build").asText();
break;
default:
FileUtils.copyURLToFile(new URL("https://api.papermc.io/v2/projects/" + project + "/versions/" + version + "/builds/" + latestbuild + "/downloads/" + project + "-" + version + "-" + latestbuild + ".jar"), new File(directory + "/server.jar"));
String[] builds = new ObjectMapper().readTree(new URL("https://api.papermc.io/v2/projects/" + project + "/versions/" + version)).get("builds").toString().replaceAll("\\[", "").replaceAll("]", "").split(",");
latestbuild = builds[builds.length - 1];
}
System.out.println("Downloaded Server");
props.setProperty("build", latestbuild);
props.store(new FileWriter(directory + "/mcscli.properties"), "MinecraftServerCLI settings");
System.out.println("Updated properties file");
if (!latestbuild.equals(props.getProperty("build"))) {
System.out.println("Downloading " + project + " version " + version + " build #" + latestbuild + "...");
switch (project) {
case "fabric":
String[] builds = latestbuild.split(":");
FileUtils.copyURLToFile(new URL("https://meta.fabricmc.net/v2/versions/loader/" + version + "/" + builds[0] + "/" + builds[1] + "/server/jar"), new File(directory + "/server.jar"));
break;
case "magma":
FileUtils.copyURLToFile(new URL("https://api.magmafoundation.org/api/v2/" + version + "/latest/" + latestbuild + "/download"), new File(directory + "/server.jar"));
break;
case "purpur":
FileUtils.copyURLToFile(new URL("https://api.purpurmc.org/v2/" + project + "/" + version + "/" + latestbuild + "/download"), new File(directory + "/server.jar"));
break;
default:
FileUtils.copyURLToFile(new URL("https://api.papermc.io/v2/projects/" + project + "/versions/" + version + "/builds/" + latestbuild + "/downloads/" + project + "-" + version + "-" + latestbuild + ".jar"), new File(directory + "/server.jar"));
}
System.out.println("Downloaded Server");
props.setProperty("build", latestbuild);
props.store(new FileWriter(directory + "/mcscli.properties"), "MinecraftServerCLI settings");
System.out.println("Updated properties file");
}
} catch (IOException e) {
System.out.println("Unable to run AutoUpdater");
}
}
} catch (MalformedURLException e) {
System.out.println("Please send exception to developer on Discord: tamion\n");
} catch(NullPointerException e) {
System.out.println("Unable to find value in Properties File. Proceeding with default values");
} catch (IOException e) {
System.out.println("Unable to read Properties file");
}
if(memory.equals("default")) {
memory = "2G";
}
System.out.println("Starting server");
new ProcessBuilder("java", "-Xms" + memory, "-Xmx" + memory, "-jar", "./server.jar", noguis)
}
if(startCommand == null) {
startCommand = "java -Xms%memory -Xmx%memory -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -jar ./server.jar %nogui";
}
if(memory == null) {
memory = "2G";
}
if(nogui == null) {
nogui = false;
}
String noguis = "";
if(nogui) {
noguis = "-nogui";
}
startCommand = startCommand
.replaceAll("%memory", memory)
.replaceAll("%nogui", noguis);
System.out.println("Starting server");
try {
new ProcessBuilder(startCommand.split(" "))
.directory(new File(directory))
.inheritIO()
.start()
.waitFor();
} catch(FileNotFoundException e) {
System.out.println("No downloadable server software found");
} catch (InterruptedException e) {
System.out.println("Server Closed");
} catch (IOException e) {
System.out.println("No Server found in Directory");
} catch (Exception e) {
throw new RuntimeException(e);
e.printStackTrace();
}
}
}

0 comments on commit 3324056

Please sign in to comment.