Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions node/impl/src/main/java/eu/cloudnetservice/node/impl/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package eu.cloudnetservice.node.impl;

import dev.derklaro.aerogel.Order;
import eu.cloudnetservice.driver.CloudNetVersion;
import eu.cloudnetservice.driver.channel.ChannelMessage;
import eu.cloudnetservice.driver.database.Database;
import eu.cloudnetservice.driver.database.DatabaseProvider;
Expand Down Expand Up @@ -80,6 +81,7 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BooleanSupplier;
import kong.unirest.core.Unirest;
import lombok.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -134,6 +136,16 @@ private void greetUser(@NonNull Console console) {
HeaderReader.readAndPrintHeader(console);
}

@Inject
@Order(75)
private void setupDefaultUnirestUserAgent(@NonNull CloudNetVersion version) {
var formattedVersion = String.format(
"%d.%d.%d-%s[%s]",
version.major(), version.minor(), version.patch(), version.versionType(), version.revision());
var userAgent = String.format("CloudNetService/CloudNet/%s (https://discord.cloudnetservice.eu)", formattedVersion);
Unirest.config().addDefaultHeader("User-Agent", userAgent);
}

@Inject
@Order(100)
private void registerDummyRPCHandlers(@NonNull RPCFactory rpcFactory, @NonNull RPCHandlerRegistry handlerRegistry) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,21 @@

import eu.cloudnetservice.driver.document.Document;
import eu.cloudnetservice.driver.document.DocumentFactory;
import eu.cloudnetservice.node.impl.version.ServiceVersionType;
import eu.cloudnetservice.node.impl.version.execute.InstallStepExecutor;
import eu.cloudnetservice.node.impl.version.information.VersionInstaller;
import eu.cloudnetservice.utils.base.StringUtil;
import io.leangen.geantyref.TypeFactory;
import java.lang.reflect.Type;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Objects;
import java.util.Set;
import kong.unirest.core.Unirest;
import lombok.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PaperApiVersionFetchStepExecutor implements InstallStepExecutor {

private static final String VERSION_LIST_URL = "https://api.papermc.io/v2/projects/%s/versions/%s";
private static final String DOWNLOAD_URL = "https://api.papermc.io/v2/projects/%s/versions/%s/builds/%d/downloads/%s-%s-%d.jar";
private static final Type INT_SET_TYPE = TypeFactory.parameterizedClass(Set.class, Integer.class);
private static final Logger LOGGER = LoggerFactory.getLogger(PaperApiVersionFetchStepExecutor.class);
private static final String LATEST_BUILD_URL = "https://fill.papermc.io/v3/projects/%s/versions/%s/builds/latest";

@Override
public @NonNull Set<Path> execute(
Expand All @@ -46,47 +44,59 @@ public class PaperApiVersionFetchStepExecutor implements InstallStepExecutor {
var enabled = installer.serviceVersion().properties().getBoolean("fetchOverPaperApi");
var versionGroup = installer.serviceVersion().properties().getString("versionGroup");
if (enabled && versionGroup != null) {
// resolve the project name we should use for the api request
var project = this.decideApiProjectName(installer.serviceVersionType());
var versionInformation = this.makeRequest(String.format(VERSION_LIST_URL, project, versionGroup));
// check if there are any builds for the version
if (versionInformation.contains("builds")) {
// extract the build numbers from the response
Set<Integer> builds = versionInformation.readObject("builds", INT_SET_TYPE);
// find the highest build number (the newest build)
var newestBuild = builds.stream().reduce(Math::max);
// check if there is a build
if (newestBuild.isPresent()) {
// set the download url of the service version required in the download step
int build = newestBuild.get();
installer.serviceVersion()
.url(String.format(DOWNLOAD_URL, project, versionGroup, build, project, versionGroup, build));
} else {
throw new IllegalStateException(
"Unable to retrieve latest build for papermc project " + project + " version-group " + versionGroup);
}
} else {
throw new IllegalStateException(
"Unable to load build information for papermc project " + project + " version-group " + versionGroup);
// resolve the download url to the latest available version for the version group
var projectName = StringUtil.toLower(installer.serviceVersionType().name());
var latestBuildUri = String.format(LATEST_BUILD_URL, projectName, versionGroup);
var latestBuildInfo = this.makeRequest(latestBuildUri);
if (latestBuildInfo.empty()) {
throw new IllegalStateException(String.format(
"Unable to load latest build info from papermc api [project=%s, versionGroup=%s]",
projectName, versionGroup));
}

LOGGER.debug(
"Latest build available in papermc api for [project={}, versionGroup={}] is {} ({})",
projectName, versionGroup, latestBuildInfo.getInt("id"), latestBuildInfo.getString("time"));

// get the available downloads (spigot and mojang mapped server jars)
var downloads = latestBuildInfo.readDocument("downloads");
var defaultMappedDownload = downloads.readDocument("server:default", null);
var mojangMappedDownload = downloads.readDocument("server:mojang", null);
if (defaultMappedDownload == null && mojangMappedDownload == null) {
throw new IllegalStateException(String.format(
"Unable to resolve download info from papermc api response for [project=%s, versionGroup=%s], got %s",
projectName, versionGroup, latestBuildInfo.serializeToString()));
}

// resolve the url to use for downloading the service version
var download = Objects.requireNonNullElse(defaultMappedDownload, mojangMappedDownload);
var downloadUrl = download.getString("url");
if (downloadUrl == null) {
throw new IllegalStateException(String.format(
"No download url provided by papermc api for [project=%s, versionGroup=%s, build=%s]",
projectName, versionGroup, latestBuildInfo.getInt("id")));
}
}
// we generated no paths
return Collections.emptySet();
}

private @NonNull Document makeRequest(@NonNull String apiUrl) {
var response = Unirest.get(apiUrl)
.accept("application/json")
.asString();
if (response.isSuccess()) {
return DocumentFactory.json().parse(response.getBody());
// update the download url for the service version
LOGGER.debug(
"Resolved download url from papermc api for [project={}, versionGroup={}, build={}] to {}",
projectName, versionGroup, latestBuildInfo.getInt("id"), downloadUrl);
installer.serviceVersion().url(downloadUrl);
}

return Document.newJsonDocument();
return Set.of();
}

@NonNull
private String decideApiProjectName(@NonNull ServiceVersionType type) {
return StringUtil.toLower(type.name());
/**
* Makes a single api request to the given uri, returning the parsed response body on success. An empty document is
* returned in case the request was not successful.
*
* @param uri the uri to send a get request to.
* @return the parsed response body in the form of a document on success, an empty document on failure.
* @throws NullPointerException if the given uri is null.
*/
private @NonNull Document makeRequest(@NonNull String uri) {
var response = Unirest.get(uri).accept("application/json").asString();
return response.isSuccess() ? DocumentFactory.json().parse(response.getBody()) : Document.emptyDocument();
}
}
30 changes: 15 additions & 15 deletions node/impl/src/main/resources/files/versions.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
},
{
"name": "1.21.5",
"url": "https://api.papermc.io/v2/projects/paper/versions/1.21.5/builds/114/downloads/paper-1.21.5-114.jar",
"url": "https://fill-data.papermc.io/v1/objects/2ae6ae22adf417699746e0f89fc2ef6cb6ee050a5f6608cee58f0535d60b509e/paper-1.21.5-114.jar",
"deprecated": true,
"properties": {
"copy": {
Expand All @@ -121,7 +121,7 @@
},
{
"name": "1.21.4",
"url": "https://api.papermc.io/v2/projects/paper/versions/1.21.4/builds/232/downloads/paper-1.21.4-232.jar",
"url": "https://fill-data.papermc.io/v1/objects/5ee4f542f628a14c644410b08c94ea42e772ef4d29fe92973636b6813d4eaffc/paper-1.21.4-232.jar",
"deprecated": true,
"properties": {
"copy": {
Expand All @@ -136,7 +136,7 @@
},
{
"name": "1.20.6",
"url": "https://api.papermc.io/v2/projects/paper/versions/1.20.6/builds/151/downloads/paper-1.20.6-151.jar",
"url": "https://fill-data.papermc.io/v1/objects/4b011f5adb5f6c72007686a223174fce82f31aeb4b34faf4652abc840b47e640/paper-1.20.6-151.jar",
"deprecated": true,
"properties": {
"copy": {
Expand All @@ -151,7 +151,7 @@
},
{
"name": "1.19.4",
"url": "https://api.papermc.io/v2/projects/paper/versions/1.19.4/builds/550/downloads/paper-1.19.4-550.jar",
"url": "https://fill-data.papermc.io/v1/objects/e587d78cba3e99ef8c4bc24cf20cc3bdbbe89e33b0b572070446af4eb6be5ccf/paper-1.19.4-550.jar",
"deprecated": true,
"properties": {
"copy": {
Expand All @@ -166,7 +166,7 @@
},
{
"name": "1.18.2",
"url": "https://api.papermc.io/v2/projects/paper/versions/1.18.2/builds/387/downloads/paper-1.18.2-387.jar",
"url": "https://fill-data.papermc.io/v1/objects/0578f18f4d632b494b468ec56b3b414b5b56fea087ee7d39cf6dcdf4c9d01f05/paper-1.18.2-388.jar",
"deprecated": true,
"properties": {
"copy": {
Expand All @@ -181,7 +181,7 @@
},
{
"name": "1.17.1",
"url": "https://api.papermc.io/v2/projects/paper/versions/1.17.1/builds/409/downloads/paper-1.17.1-409.jar",
"url": "https://fill-data.papermc.io/v1/objects/6cc1ee2f94253ce10b5374ed85fffc735a97d8f1b64db293683dfa24dd3cc05f/paper-1.17.1-411.jar",
"deprecated": true,
"properties": {
"copy": {
Expand All @@ -194,7 +194,7 @@
},
{
"name": "1.16.5",
"url": "https://api.papermc.io/v2/projects/paper/versions/1.16.5/builds/794/downloads/paper-1.16.5-794.jar",
"url": "https://fill-data.papermc.io/v1/objects/e67da4851d08cde378ab2b89be58849238c303351ed2482181a99c2c2b489276/paper-1.16.5-794.jar",
"deprecated": true,
"properties": {
"copy": {
Expand All @@ -207,7 +207,7 @@
},
{
"name": "1.15.2",
"url": "https://api.papermc.io/v2/projects/paper/versions/1.15.2/builds/393/downloads/paper-1.15.2-393.jar",
"url": "https://fill-data.papermc.io/v1/objects/bd2dd6f2cc489cf9e2bb800cb4fb6d63e9d293945d3ac10b09dd9c6098fa9f34/paper-1.15.2-393.jar",
"deprecated": true,
"properties": {
"copy": {
Expand All @@ -220,7 +220,7 @@
},
{
"name": "1.14.4",
"url": "https://api.papermc.io/v2/projects/paper/versions/1.14.4/builds/245/downloads/paper-1.14.4-245.jar",
"url": "https://fill-data.papermc.io/v1/objects/bd8ec5cdb22370d37816a6de26798df3d2b0d6f9c7c96c88ca45a1303fea50e8/paper-1.14.4-245.jar",
"deprecated": true,
"properties": {
"copy": {
Expand All @@ -233,7 +233,7 @@
},
{
"name": "1.13.2",
"url": "https://api.papermc.io/v2/projects/paper/versions/1.13.2/builds/657/downloads/paper-1.13.2-657.jar",
"url": "https://fill-data.papermc.io/v1/objects/11e828d0565ab76a0a0e180c056364a95de44958cfd6a6af3f9b1dc70b03e9cd/paper-1.13.2-657.jar",
"deprecated": true,
"properties": {
"copy": {
Expand All @@ -246,7 +246,7 @@
},
{
"name": "1.12.2",
"url": "https://api.papermc.io/v2/projects/paper/versions/1.12.2/builds/1620/downloads/paper-1.12.2-1620.jar",
"url": "https://fill-data.papermc.io/v1/objects/3a2041807f492dcdc34ebb324a287414946e3e05ec3df6fd03f5b5f7d9afc210/paper-1.12.2-1620.jar",
"deprecated": true,
"properties": {
"copy": {
Expand All @@ -259,7 +259,7 @@
},
{
"name": "1.11.2",
"url": "https://api.papermc.io/v2/projects/paper/versions/1.11.2/builds/1106/downloads/paper-1.11.2-1106.jar",
"url": "https://fill-data.papermc.io/v1/objects/3d0f40ec1f9630dfdbafa626cc20c266d7fb90fc22583dc1b995e7fbfb76830d/paper-1.11.2-1106.jar",
"deprecated": true,
"properties": {
"copy": {
Expand All @@ -272,7 +272,7 @@
},
{
"name": "1.10.2",
"url": "https://api.papermc.io/v2/projects/paper/versions/1.10.2/builds/918/downloads/paper-1.10.2-918.jar",
"url": "https://fill-data.papermc.io/v1/objects/83354d24a22b6265e76c089b3d17a568abb446c0ccd12c2452f5e148412b16c2/paper-1.10.2-918.jar",
"deprecated": true,
"properties": {
"copy": {
Expand All @@ -285,7 +285,7 @@
},
{
"name": "1.9.4",
"url": "https://api.papermc.io/v2/projects/paper/versions/1.9.4/builds/775/downloads/paper-1.9.4-775.jar",
"url": "https://fill-data.papermc.io/v1/objects/15a5821ddeacc596432c3fbf24262a2d264f556060ecd6f1838fb01ab5629a81/paper-1.9.4-775.jar",
"deprecated": true,
"properties": {
"copy": {
Expand All @@ -295,7 +295,7 @@
},
{
"name": "1.8.8",
"url": "https://api.papermc.io/v2/projects/paper/versions/1.8.8/builds/445/downloads/paper-1.8.8-445.jar",
"url": "https://fill-data.papermc.io/v1/objects/7ff6d2cec671ef0d95b3723b5c92890118fb882d73b7f8fa0a2cd31d97c55f86/paper-1.8.8-445.jar",
"deprecated": true,
"properties": {
"copy": {
Expand Down
Loading