Initial commit
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
package org.strassburger.mcrun;
|
||||
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugin.MojoFailureException;
|
||||
import org.apache.maven.plugins.annotations.LifecyclePhase;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.strassburger.mcrun.downloader.PaperServerJarDownloader;
|
||||
import org.strassburger.mcrun.downloader.ServerJarDownloadException;
|
||||
import org.strassburger.mcrun.downloader.ServerJarDownloader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
|
||||
@Mojo(name = "run", defaultPhase = LifecyclePhase.PACKAGE)
|
||||
public class RunServerMojo extends AbstractMojo {
|
||||
@Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}.jar")
|
||||
private File pluginJar;
|
||||
|
||||
@Parameter(defaultValue = "${project.basedir}/server")
|
||||
private File serverDirectory;
|
||||
|
||||
@Parameter(defaultValue = "server.jar")
|
||||
private String serverJarName;
|
||||
|
||||
@Parameter(defaultValue = "paper")
|
||||
private String serverSoftware;
|
||||
|
||||
@Parameter(required = true)
|
||||
private String mcVersion;
|
||||
|
||||
@Parameter(defaultValue = "2G")
|
||||
private String memory;
|
||||
|
||||
@Parameter(defaultValue = "true")
|
||||
private boolean acceptEula;
|
||||
|
||||
@Override
|
||||
public void execute() throws MojoExecutionException, MojoFailureException {
|
||||
getLog().info("Server directory: " + serverDirectory.getAbsolutePath());
|
||||
|
||||
File pluginsDir = new File(serverDirectory, "plugins");
|
||||
pluginsDir.mkdirs();
|
||||
try {
|
||||
Files.copy(pluginJar.toPath(),
|
||||
new File(pluginsDir, pluginJar.getName()).toPath(),
|
||||
StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (IOException e) {
|
||||
throw new MojoExecutionException("Failed to copy plugin jar file: " + pluginJar.getAbsolutePath(), e);
|
||||
}
|
||||
|
||||
try {
|
||||
ServerJarDownloader jarDownloader = ServerJarDownloader.forServerSoftware(serverSoftware)
|
||||
.withLog(getLog()).withServerDirectory(serverDirectory)
|
||||
.withServerJarName(serverJarName).withMcVersion(mcVersion)
|
||||
.build();
|
||||
jarDownloader.run();
|
||||
} catch (ServerJarDownloadException e) {
|
||||
throw new MojoExecutionException("Failed to download server jar", e);
|
||||
}
|
||||
if (acceptEula) acceptEula();
|
||||
|
||||
ProcessBuilder pb = new ProcessBuilder(
|
||||
"java", "-Xmx" + memory, "-Xms" + memory,
|
||||
"-jar", serverJarName, "--nogui"
|
||||
);
|
||||
pb.directory(serverDirectory);
|
||||
pb.inheritIO();
|
||||
Process process;
|
||||
try {
|
||||
process = pb.start();
|
||||
} catch (IOException e) {
|
||||
throw new MojoExecutionException("Failed to start server: " + e.getMessage(), e);
|
||||
}
|
||||
try {
|
||||
process.waitFor();
|
||||
} catch (InterruptedException e) {
|
||||
throw new MojoExecutionException("Failed to start server: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void acceptEula() throws MojoExecutionException {
|
||||
File eula = new File(serverDirectory, "eula.txt");
|
||||
if (eula.exists()) return;
|
||||
try {
|
||||
Files.writeString(eula.toPath(), "eula=true\n");
|
||||
getLog().info("eula.txt created and accepted.");
|
||||
} catch (IOException e) {
|
||||
throw new MojoExecutionException("Failed to write eula.txt: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package org.strassburger.mcrun.downloader;
|
||||
|
||||
import org.apache.maven.plugin.logging.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
|
||||
public class PaperServerJarDownloader extends ServerJarDownloader {
|
||||
|
||||
public PaperServerJarDownloader(Log log, File serverDirectory, String serverJarName, String mcVersion) {
|
||||
super(log, serverDirectory, serverJarName, mcVersion);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void downloadServerJar() throws ServerJarDownloadException {
|
||||
File jarFile = getServerJar();
|
||||
|
||||
try {
|
||||
getLog().info("Fetching latest Paper build info for " + getMcVersion() + "...");
|
||||
String apiUrl = "https://fill.papermc.io/v3/projects/paper/versions/" + getMcVersion() + "/builds/latest";
|
||||
String json = fetchUrl(apiUrl);
|
||||
|
||||
String downloadUrl = parseDownloadUrl(json);
|
||||
getLog().info("Downloading Paper from: " + downloadUrl);
|
||||
|
||||
try (var in = new java.net.URI(downloadUrl).toURL().openStream()) {
|
||||
Files.copy(in, jarFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
getLog().info("Paper downloaded to: " + jarFile.getAbsolutePath());
|
||||
} catch (Exception e) {
|
||||
throw new ServerJarDownloadException("Failed to download Paper: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private String fetchUrl(String url) throws Exception {
|
||||
var connection = new java.net.URI(url).toURL().openConnection();
|
||||
connection.setRequestProperty("Accept", "application/json");
|
||||
try (var in = connection.getInputStream()) {
|
||||
return new String(in.readAllBytes());
|
||||
}
|
||||
}
|
||||
|
||||
private String parseDownloadUrl(String json) {
|
||||
// Parse: .downloads["server:default"].url
|
||||
int downloadsIdx = json.indexOf("\"downloads\"");
|
||||
int serverDefaultIdx = json.indexOf("\"server:default\"", downloadsIdx);
|
||||
int urlIdx = json.indexOf("\"url\"", serverDefaultIdx);
|
||||
int urlStart = json.indexOf("\"", urlIdx + 5) + 1;
|
||||
int urlEnd = json.indexOf("\"", urlStart);
|
||||
|
||||
if (urlStart <= 0 || urlEnd <= 0) {
|
||||
throw new ServerJarDownloadException("Could not parse download URL from Paper API response");
|
||||
}
|
||||
|
||||
return json.substring(urlStart, urlEnd);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.strassburger.mcrun.downloader;
|
||||
|
||||
public class ServerJarDownloadException extends RuntimeException {
|
||||
public ServerJarDownloadException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ServerJarDownloadException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package org.strassburger.mcrun.downloader;
|
||||
|
||||
import org.apache.maven.plugin.logging.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.function.Function;
|
||||
|
||||
public abstract class ServerJarDownloader {
|
||||
private final Log log;
|
||||
private final File serverDirectory;
|
||||
private final String serverJarName;
|
||||
private final String mcVersion;
|
||||
|
||||
public ServerJarDownloader(Log log, File serverDirectory, String serverJarName, String mcVersion) {
|
||||
this.log = log;
|
||||
this.serverDirectory = serverDirectory;
|
||||
this.serverJarName = serverJarName;
|
||||
this.mcVersion = mcVersion;
|
||||
}
|
||||
|
||||
public void run() throws ServerJarDownloadException {
|
||||
if (getServerJar().exists()) {
|
||||
log.info("Paper jar already exists, skipping download.");
|
||||
return;
|
||||
}
|
||||
|
||||
serverDirectory.mkdirs();
|
||||
|
||||
downloadServerJar();
|
||||
}
|
||||
|
||||
protected Log getLog() {
|
||||
return log;
|
||||
}
|
||||
|
||||
protected String getMcVersion() {
|
||||
return mcVersion;
|
||||
}
|
||||
|
||||
protected File getServerJar() {
|
||||
return new File(serverDirectory, serverJarName);
|
||||
}
|
||||
|
||||
protected abstract void downloadServerJar() throws ServerJarDownloadException;
|
||||
|
||||
public static Builder forServerSoftware(String serverSoftware) throws ServerJarDownloadException {
|
||||
return switch (serverSoftware) {
|
||||
case "paper" -> new Builder(b ->
|
||||
new PaperServerJarDownloader(b.log, b.serverDirectory, b.serverJarName, b.mcVersion));
|
||||
default -> throw new ServerJarDownloadException("Invalid server software: " + serverSoftware);
|
||||
};
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final Function<Builder, ServerJarDownloader> factory;
|
||||
private Log log;
|
||||
private File serverDirectory;
|
||||
private String serverJarName;
|
||||
private String mcVersion;
|
||||
|
||||
public Builder(Function<Builder, ServerJarDownloader> factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public Builder withLog(Log log) {
|
||||
this.log = log;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withServerDirectory(File serverDirectory) {
|
||||
this.serverDirectory = serverDirectory;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withServerJarName(String serverJarName) {
|
||||
this.serverJarName = serverJarName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withMcVersion(String mcVersion) {
|
||||
this.mcVersion = mcVersion;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerJarDownloader build() {
|
||||
return factory.apply(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user