From 7ad2f6693ecbc339c11458f418346da994f74b2e Mon Sep 17 00:00:00 2001 From: Griefed Date: Fri, 11 Aug 2023 20:01:44 +0200 Subject: [PATCH] feat: Support NeoForge modloader --- .../src/commonMain/i18n/Api_en_GB.properties | 2 +- .../serverpackcreator/api/Configuration.kt | 6 +- .../de/griefed/serverpackcreator/api/Pack.kt | 3 + .../serverpackcreator/api/versionmeta/Type.kt | 5 + .../api/versionmeta/VersionMeta.kt | 11 +- .../api/versionmeta/neoforge/NeoForgeMeta.kt | 220 ++++++++++ .../serverpackcreator/api/ApiProperties.kt | 11 +- .../serverpackcreator/api/ApiWrapper.kt | 1 + .../api/ConfigurationHandler.kt | 11 + .../serverpackcreator/api/PackConfig.kt | 2 +- .../api/ServerPackHandler.kt | 19 + .../api/versionmeta/VersionMeta.kt | 25 +- .../versionmeta/neoforge/NeoForgeInstance.kt | 54 +++ .../versionmeta/neoforge/NeoForgeLoader.kt | 127 ++++++ .../api/versionmeta/neoforge/NeoForgeMeta.kt | 391 ++++++++++++++++++ .../server_files/default_template.ps1 | 74 ++++ .../server_files/default_template.sh | 67 +++ .../gui/window/configs/ConfigEditor.kt | 21 + .../web/BeanConfiguration.kt | 5 + 19 files changed, 1047 insertions(+), 8 deletions(-) create mode 100644 serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/neoforge/NeoForgeMeta.kt create mode 100644 serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/neoforge/NeoForgeInstance.kt create mode 100644 serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/neoforge/NeoForgeLoader.kt create mode 100644 serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/neoforge/NeoForgeMeta.kt diff --git a/serverpackcreator-api/src/commonMain/i18n/Api_en_GB.properties b/serverpackcreator-api/src/commonMain/i18n/Api_en_GB.properties index f06d06696..046e77778 100644 --- a/serverpackcreator-api/src/commonMain/i18n/Api_en_GB.properties +++ b/serverpackcreator-api/src/commonMain/i18n/Api_en_GB.properties @@ -17,7 +17,7 @@ configuration.log.error.checkcopydirs.read=No read-permission for {0} configuration.log.error.checkcopydirs.checkforregex=Invalid regex entry: {0} configuration.log.error.checkcopydirs.checkforregex.invalid=Entry must contain, or start with, == configuration.log.error.checkcopydirs.checkforregex.invalid.regex=Invalid regex specified: {0}. Error near regex-index {1}. -configuration.log.error.checkmodloader=Invalid modloader specified. Modloader must be either Forge, Fabric or Quilt. +configuration.log.error.checkmodloader=Invalid modloader specified. Modloader must be either Forge, NeoForge, Fabric, Quilt or LegacyFabric. configuration.log.error.checkmodloaderversion=Specified incorrect modloader version. Please check your modpack for the correct version and enter again. configuration.log.error.checkmodloaderandversion=Minecraft {0} and {1} {2} are not compatible. configuration.log.error.isdir.copydir=There's something wrong with your setting of directories to include in your server pack. diff --git a/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/Configuration.kt b/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/Configuration.kt index 073665ca5..6ac1b105c 100644 --- a/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/Configuration.kt +++ b/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/Configuration.kt @@ -33,6 +33,7 @@ import mu.KotlinLogging abstract class Configuration { protected val log = KotlinLogging.logger {} protected val forge = "^forge$".toRegex() + protected val neoForge = "^neoforge$".toRegex() protected val fabric = "^fabric$".toRegex() protected val quilt = "^quilt$".toRegex() protected val legacyFabric = "^legacyfabric$".toRegex() @@ -160,6 +161,7 @@ abstract class Configuration { */ fun checkModloader(modloader: String) = if (modloader.lowercase().matches(forge) + || modloader.lowercase().matches(neoForge) || modloader.lowercase().matches(fabric) || modloader.lowercase().matches(quilt) || modloader.lowercase().matches(legacyFabric) @@ -223,9 +225,7 @@ abstract class Configuration { * @author Griefed */ fun printEncounteredErrors(encounteredErrors: List) { - log.error( - "Encountered ${encounteredErrors.size} errors during the configuration check." - ) + log.error("Encountered ${encounteredErrors.size} errors during the configuration check.") var encounteredErrorNumber: Int for (i in encounteredErrors.indices) { encounteredErrorNumber = i + 1 diff --git a/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/Pack.kt b/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/Pack.kt index e0aa779cd..dda0dcd8b 100644 --- a/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/Pack.kt +++ b/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/Pack.kt @@ -29,6 +29,7 @@ import de.griefed.serverpackcreator.api.utilities.CommentedConfig @Suppress("MemberVisibilityCanBePrivate") abstract class Pack { protected val forge = "^forge$".toRegex() + protected val neoForge = "^neoforge$".toRegex() protected val fabric = "^fabric$".toRegex() protected val quilt = "^quilt$".toRegex() protected val legacyFabric = "^legacyfabric$".toRegex() @@ -49,6 +50,8 @@ abstract class Pack { set(newModLoader) { if (newModLoader.lowercase().matches(forge)) { field = "Forge" + } else if (newModLoader.lowercase().matches(neoForge)) { + field = "NeoForge" } else if (newModLoader.lowercase().matches(fabric)) { field = "Fabric" } else if (newModLoader.lowercase().matches(quilt)) { diff --git a/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/Type.kt b/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/Type.kt index 8b0748cd8..8fe412d8c 100644 --- a/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/Type.kt +++ b/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/Type.kt @@ -45,6 +45,11 @@ enum class Type { */ FORGE, + /** + * Indicates this operation concerns NeoForge. + */ + NEO_FORGE, + /** * Indicates this operation concerns Fabric. */ diff --git a/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/VersionMeta.kt b/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/VersionMeta.kt index a25140530..52d2b9d9e 100644 --- a/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/VersionMeta.kt +++ b/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/VersionMeta.kt @@ -23,6 +23,7 @@ package de.griefed.serverpackcreator.api.versionmeta import de.griefed.serverpackcreator.api.utilities.URL import de.griefed.serverpackcreator.api.versionmeta.fabric.FabricMeta import de.griefed.serverpackcreator.api.versionmeta.forge.ForgeMeta +import de.griefed.serverpackcreator.api.versionmeta.neoforge.NeoForgeMeta import de.griefed.serverpackcreator.api.versionmeta.legacyfabric.LegacyFabricMeta import de.griefed.serverpackcreator.api.versionmeta.minecraft.MinecraftMeta import de.griefed.serverpackcreator.api.versionmeta.quilt.QuiltMeta @@ -48,6 +49,9 @@ expect class VersionMeta { @Suppress("MemberVisibilityCanBePrivate") val forgeUrlManifest: URL + @Suppress("MemberVisibilityCanBePrivate") + val neoForgeUrlManifest: URL + @Suppress("MemberVisibilityCanBePrivate") val fabricUrlManifest: URL @@ -81,6 +85,12 @@ expect class VersionMeta { @Suppress("MemberVisibilityCanBePrivate") val forge: ForgeMeta + /** + * The NeoForgeMeta-instance for working with NeoForge versions and information about them. + */ + @Suppress("MemberVisibilityCanBePrivate") + val neoForge: NeoForgeMeta + /** * The QuiltMeta-instance for working with Quilt versions and information about them. */ @@ -92,5 +102,4 @@ expect class VersionMeta { */ @Suppress("MemberVisibilityCanBePrivate") val legacyFabric: LegacyFabricMeta - } \ No newline at end of file diff --git a/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/neoforge/NeoForgeMeta.kt b/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/neoforge/NeoForgeMeta.kt new file mode 100644 index 000000000..adda7d137 --- /dev/null +++ b/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/neoforge/NeoForgeMeta.kt @@ -0,0 +1,220 @@ +package de.griefed.serverpackcreator.api.versionmeta.neoforge + +import de.griefed.serverpackcreator.api.utilities.common.Utilities +import java.io.File +import java.net.URL +import java.util.* + +/** + * Forge meta containing information about available Forge releases. + * + * @param neoForgeManifest The manifest from which to acquire version information. + * @param utilities Commonly used utilities across ServerPackCreator. + * + * @author Griefed + */ +@Suppress("unused") +expect class NeoForgeMeta( + neoForgeManifest: File, + utilities: Utilities, + installerCacheDirectory: File +) { + /** + * Check whether the given Minecraft and Forge versions are valid/supported/available. + * + * @param minecraftVersion Minecraft version. + * @param neoForgeVersion Forge version. + * @return `true` if the given Minecraft and Forge versions are valid/supported/available. + * @author Griefed + */ + fun isNeoForgeAndMinecraftCombinationValid( + minecraftVersion: String, + neoForgeVersion: String + ): Boolean + + /** + * Check whether a given Minecraft version is valid/supported/available. + * + * @param minecraftVersion Minecraft version. + * @return `true` if the given Minecraft version is valid/supported/available. + * @author Griefed + */ + fun isMinecraftVersionSupported(minecraftVersion: String): Boolean + + /** + * Check whether a given Forge version is valid/supported/available. + * + * @param neoForgeVersion Forge version. + * @return `true` if the given Forge version is valid/supported/available. + * @author Griefed + */ + fun isNeoForgeVersionValid(neoForgeVersion: String): Boolean + + /** + * Check whether Forge is available for a given Forge- and Minecraft version. + * + * @param minecraftVersion Minecraft version. + * @param neoForgeVersion Forge version. + * @return `true` if Forge is available for the given Forge- and Minecraft version. + * @author Griefed + */ + fun isNeoForgeInstanceAvailable(minecraftVersion: String, neoForgeVersion: String): Boolean + + /** + * Check whether Forge is available for a given Forge version + * + * @param neoForgeVersion Forge version. + * @return `true` if Forge is available for the given Forge version. + * @author Griefed + */ + fun isNeoForgeInstanceAvailable(neoForgeVersion: String): Boolean + + /** + * Latest Forge version for a given Minecraft version, wrapped in [Optional] + * + * @param minecraftVersion Minecraft version. + * @return Latest Forge version for the given Minecraft version, wrapped in an [Optional] + * @author Griefed + */ + fun newestNeoForgeVersion(minecraftVersion: String): Optional + + /** + * Oldest Forge version for a given Minecraft version, wrapped in [Optional] + * + * @param minecraftVersion Minecraft version. + * @return Oldest Forge version for the given Minecraft version, wrapped in [Optional] + * @author Griefed + */ + fun oldestNeoForgeVersion(minecraftVersion: String): Optional + + /** + * Get the list of available Forge versions, in ascending order. + * + * @return List of available Forge versions. + * @author Griefed + */ + fun neoForgeVersionsAscending(): MutableList + + /** + * Get the list of available Forge versions, in descending order. + * + * @return List of available Forge versions. + * @author Griefed + */ + fun neoForgeVersionsDescending(): List + + /** + * Get the array of available Forge versions, in ascending order. + * + * @return Array of available Forge versions. + * @author Griefed + */ + fun neoForgeVersionsAscendingArray(): Array + + /** + * Get the array of available Forge versions, in descending order. + * + * @return Array of available Forge versions. + * @author Griefed + */ + fun neoForgeVersionsDescendingArray(): Array + + /** + * Get a list of available Forge version for a given Minecraft version in ascending order. + * + * @param minecraftVersion Minecraft version. + * @return List of available Forge versions for the given Minecraft version in ascending order. + * @author Griefed + */ + fun supportedNeoForgeVersionsAscending(minecraftVersion: String): Optional> + + /** + * Get a list of available Forge version for a given Minecraft version in descending order. + * + * @param minecraftVersion Minecraft version. + * @return List of available Forge versions for the given Minecraft version in descending order. + * @author Griefed + */ + fun supportedNeoForgeVersionsDescending(minecraftVersion: String): Optional> + + /** + * Get an array of available Forge version for a given Minecraft version, in ascending order, + * wrapped in an [Optional]. + * + * @param minecraftVersion Minecraft version. + * @return Array of available Forge versions for the given Minecraft version, in ascending order, + * wrapped in an [Optional] + * @author Griefed + */ + fun supportedNeoForgeVersionsAscendingArray(minecraftVersion: String): Optional> + + /** + * Get an array of available Forge version for a given Minecraft version, in descending order, + * wrapped in an [Optional]. + * + * @param minecraftVersion Minecraft version. + * @return Array of available Forge versions for the given Minecraft version, in descending order, + * wrapped in an [Optional] + * @author Griefed + */ + fun supportedNeoForgeVersionsDescendingArray(minecraftVersion: String): Optional> + + /** + * Get the Minecraft version for a given Forge version, wrapped in an [Optional]. + * + * @param neoForgeVersion Forge version. + * @return Minecraft version for the given Forge version, wrapped in an [Optional]. + * @author Griefed + */ + fun minecraftVersion(neoForgeVersion: String): Optional + + /** + * Get the list of Forge supported Minecraft versions, in ascending order. + * + * @return List of Forge supported Minecraft versions, in ascending order. + * @author Griefed + */ + fun supportedMinecraftVersionsAscending(): MutableList + + /** + * Get the list of Forge supported Minecraft versions, in descending order. + * + * @return List of Forge supported Minecraft versions, in descending order. + * @author Griefed + */ + fun supportedMinecraftVersionsDescending(): List + + /** + * Get the array of Forge supported Minecraft versions, in ascending order. + * + * @return Array of Forge supported Minecraft versions, in ascending order. + * @author Griefed + */ + fun supportedMinecraftVersionsAscendingArray(): Array + + /** + * Get the array of Forge supported Minecraft versions, in descending order. + * + * @return Array of Forge supported Minecraft versions, in descending order. + * @author Griefed + */ + fun supportedMinecraftVersionsDescendingArray(): Array + + /** + * Get the Forge server installer URL for a given Forge version, wrapped in an [Optional]. + * + * @param neoForgeVersion Forge version. + * @return Forge server installer URL for the given Forge version, wrapped in an [Optional]. + * @author Griefed + */ + fun installerUrl(neoForgeVersion: String): Optional + + /** + * Installer file for the specified [neoForgeVersion] and [minecraftVersion] version, wrapped in an [Optional], so you + * can check whether it is available first. + * @author Griefed + */ + fun installerFor(neoForgeVersion: String, minecraftVersion: String): Optional + + +} \ No newline at end of file diff --git a/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/ApiProperties.kt b/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/ApiProperties.kt index db0353f98..330e6c7c9 100644 --- a/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/ApiProperties.kt +++ b/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/ApiProperties.kt @@ -491,7 +491,7 @@ actual class ApiProperties( /** * Modloaders supported by ServerPackCreator. */ - val supportedModloaders = arrayOf("Fabric", "Forge", "Quilt", "LegacyFabric") + val supportedModloaders = arrayOf("Fabric", "Forge", "Quilt", "LegacyFabric", "NeoForge") /** * The folder containing the ServerPackCreator.exe or JAR-file. @@ -1230,6 +1230,15 @@ actual class ApiProperties( */ val forgeVersionManifest: File = File(manifestsDirectory, "forge-manifest.json").absoluteFile + /** + * NeoForge version manifest containing information about available NeoForge loader versions. + * + * + * By default, the `neoforge-manifest.xml`-file resides in the `manifests`-directory + * inside ServerPackCreators home-directory. + */ + val neoForgeVersionManifest: File = File(manifestsDirectory, "neoforge-manifest.xml").absoluteFile + /** * Fabric version manifest containing information about available Fabric loader versions. * diff --git a/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/ApiWrapper.kt b/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/ApiWrapper.kt index c0235fca1..4c3b49e30 100644 --- a/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/ApiWrapper.kt +++ b/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/ApiWrapper.kt @@ -184,6 +184,7 @@ actual class ApiWrapper private constructor( field = VersionMeta( apiProperties.minecraftVersionManifest, apiProperties.forgeVersionManifest, + apiProperties.neoForgeVersionManifest, apiProperties.fabricVersionManifest, apiProperties.fabricInstallerManifest, apiProperties.fabricIntermediariesManifest, diff --git a/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/ConfigurationHandler.kt b/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/ConfigurationHandler.kt index ebd3d81aa..076ad3ebe 100644 --- a/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/ConfigurationHandler.kt +++ b/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/ConfigurationHandler.kt @@ -388,6 +388,17 @@ actual class ConfigurationHandler( false } + "NeoForge" -> if (versionMeta.neoForge.isNeoForgeAndMinecraftCombinationValid(minecraftVersion, modloaderVersion)) { + true + } else { + encounteredErrors.add( + Api.configuration_log_error_checkmodloaderandversion( + minecraftVersion, modloader, modloaderVersion + ) + ) + false + } + "Fabric" -> if (versionMeta.fabric.isVersionValid(modloaderVersion) && versionMeta.fabric.getLoaderDetails( minecraftVersion, modloaderVersion diff --git a/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/PackConfig.kt b/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/PackConfig.kt index 716d5b858..bb799de77 100644 --- a/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/PackConfig.kt +++ b/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/PackConfig.kt @@ -296,7 +296,7 @@ actual open class PackConfig actual constructor() : Pack("minecraftVersion", minecraftVersion) conf.setComment( "modLoader", - "\n Which modloader to install. Must be either \"Forge\", \"Fabric\", \"Quilt\" or \"LegacyFabric\".\n Automatically set when projectID,fileID for modpackDir has been specified.\n Only needed if includeServerInstallation is true." + "\n Which modloader to install. Must be either \"Forge\", \"NeoForge\", \"Fabric\", \"Quilt\" or \"LegacyFabric\".\n Automatically set when projectID,fileID for modpackDir has been specified.\n Only needed if includeServerInstallation is true." ) conf.set("modLoader", modloader) val plugins: Config = TomlFormat.newConfig() diff --git a/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/ServerPackHandler.kt b/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/ServerPackHandler.kt index 0ae316d8e..27639ce66 100644 --- a/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/ServerPackHandler.kt +++ b/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/ServerPackHandler.kt @@ -580,6 +580,25 @@ actual class ServerPackHandler actual constructor( } } + "NeoForge" -> { + log.info { "Installing Forge server." } + installerLog.info("Starting Forge installation.") + if (versionMeta.neoForge.installerFor(modLoaderVersion, minecraftVersion).isPresent) { + log.info("NeoForge installer successfully downloaded.") + val installer = + versionMeta.neoForge.installerFor(modLoaderVersion, minecraftVersion).get().absolutePath + commandArguments.addMultiple( + installer, + "--installServer" + ) + } else { + log.error( + "Something went wrong during the installation of NeoForge. Maybe the NeoForge servers are down or unreachable? Skipping..." + ) + return + } + } + "Quilt" -> { log.info { "Installing Quilt server." } installerLog.info("Starting Quilt installation.") diff --git a/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/VersionMeta.kt b/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/VersionMeta.kt index 9aee097bb..d0db083dc 100644 --- a/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/VersionMeta.kt +++ b/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/VersionMeta.kt @@ -29,6 +29,7 @@ import de.griefed.serverpackcreator.api.versionmeta.fabric.FabricMeta import de.griefed.serverpackcreator.api.versionmeta.forge.ForgeMeta import de.griefed.serverpackcreator.api.versionmeta.legacyfabric.LegacyFabricMeta import de.griefed.serverpackcreator.api.versionmeta.minecraft.MinecraftMeta +import de.griefed.serverpackcreator.api.versionmeta.neoforge.NeoForgeMeta import de.griefed.serverpackcreator.api.versionmeta.quilt.QuiltMeta import kotlinx.coroutines.* import org.apache.logging.log4j.kotlin.cachedLoggerOf @@ -64,6 +65,7 @@ import javax.xml.parsers.ParserConfigurationException actual class VersionMeta( private val minecraftManifest: File, private val forgeManifest: File, + private val neoForgeManifest: File, private val fabricManifest: File, private val fabricInstallerManifest: File, private val fabricIntermediariesManifest: File, @@ -99,6 +101,10 @@ actual class VersionMeta( actual val forgeUrlManifest = URL("https://files.minecraftforge.net/net/minecraftforge/forge/maven-metadata.json") + @Suppress("MemberVisibilityCanBePrivate") + actual val neoForgeUrlManifest = + URL("https://maven.neoforged.net/releases/net/neoforged/forge/maven-metadata.xml") + @Suppress("MemberVisibilityCanBePrivate") actual val fabricUrlManifest = URL("https://maven.fabricmc.net/net/fabricmc/fabric-loader/maven-metadata.xml") @@ -137,6 +143,12 @@ actual class VersionMeta( @Suppress("MemberVisibilityCanBePrivate") actual val forge: ForgeMeta + /** + * The NeoForgeMeta-instance for working with NeoForge versions and information about them. + */ + @Suppress("MemberVisibilityCanBePrivate") + actual val neoForge: NeoForgeMeta + /** * The QuiltMeta-instance for working with Quilt versions and information about them. */ @@ -159,6 +171,11 @@ actual class VersionMeta( utilities, apiProperties.installerCacheDirectory ) + neoForge = NeoForgeMeta( + neoForgeManifest, + utilities, + apiProperties.installerCacheDirectory + ) minecraft = MinecraftMeta( minecraftManifest, forge, @@ -185,6 +202,7 @@ actual class VersionMeta( apiProperties.installerCacheDirectory ) forge.initialize(minecraft) + neoForge.initialize(minecraft) quilt = QuiltMeta( quiltManifest, quiltInstallerManifest, @@ -197,6 +215,7 @@ actual class VersionMeta( fabric.update() legacyFabric.update() forge.update() + neoForge.update() quilt.update() } @@ -216,6 +235,9 @@ actual class VersionMeta( launch { checkManifest(forgeManifest, forgeUrlManifest, Type.FORGE) } + launch { + checkManifest(neoForgeManifest, neoForgeUrlManifest, Type.NEO_FORGE) + } launch { checkManifest(fabricIntermediariesManifest, fabricUrlIntermediariesManifest, Type.FABRIC_INTERMEDIARIES) } @@ -297,7 +319,7 @@ actual class VersionMeta( countNewFile = utilities.jsonUtilities.getJson(newContent).size() } - Type.FABRIC, Type.FABRIC_INSTALLER, Type.QUILT, Type.QUILT_INSTALLER -> { + Type.FABRIC, Type.FABRIC_INSTALLER, Type.QUILT, Type.QUILT_INSTALLER, Type.NEO_FORGE -> { countOldFile = utilities.xmlUtilities.getXml(oldContent) .getElementsByTagName("version").length countNewFile = utilities.xmlUtilities.getXml(newContent) @@ -425,6 +447,7 @@ actual class VersionMeta( fabric.update() legacyFabric.update() forge.update() + neoForge.update() quilt.update() return this } diff --git a/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/neoforge/NeoForgeInstance.kt b/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/neoforge/NeoForgeInstance.kt new file mode 100644 index 000000000..c68b03008 --- /dev/null +++ b/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/neoforge/NeoForgeInstance.kt @@ -0,0 +1,54 @@ +/* Copyright (C) 2023 Griefed + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * The full license can be found at https:github.com/Griefed/ServerPackCreator/blob/main/LICENSE + */ +package de.griefed.serverpackcreator.api.versionmeta.neoforge + +import de.griefed.serverpackcreator.api.versionmeta.minecraft.MinecraftMeta +import java.net.URL +import java.util.* + +/** + * An instance of a complete NeoForge combination, containing a Minecraft version, related NeoForge + * version and the URL to the server installer. + * + * @param minecraftVersion Minecraft version. + * @param neoForgeVersion NeoForge version. + * @param minecraftMeta The corresponding Minecraft client for this NeoForge version. + * @throws [java.net.MalformedURLException] if the URL to the download of the Forge server installer could not be created. + * + * @author Griefed + */ +@Suppress("unused") +class NeoForgeInstance( + val minecraftVersion: String, + val neoForgeVersion: String, + private val minecraftMeta: MinecraftMeta +) { + val installerUrl: URL = + URL("https://maven.neoforged.net/releases/net/neoforged/forge/$minecraftVersion-$neoForgeVersion/forge-$minecraftVersion-$neoForgeVersion-installer.jar") + + /** + * Get this Forge instances corresponding Minecraft client instance, wrapped in an + * [Optional] + * + * @return Client wrapped in an [Optional]. + * @author Griefed + */ + fun minecraftClient() = minecraftMeta.getClient(minecraftVersion) +} \ No newline at end of file diff --git a/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/neoforge/NeoForgeLoader.kt b/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/neoforge/NeoForgeLoader.kt new file mode 100644 index 000000000..a782ceef3 --- /dev/null +++ b/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/neoforge/NeoForgeLoader.kt @@ -0,0 +1,127 @@ +/* Copyright (C) 2023 Griefed + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * The full license can be found at https:github.com/Griefed/ServerPackCreator/blob/main/LICENSE + */ +package de.griefed.serverpackcreator.api.versionmeta.neoforge + +import de.griefed.serverpackcreator.api.utilities.common.Utilities +import de.griefed.serverpackcreator.api.versionmeta.minecraft.MinecraftMeta +import org.apache.logging.log4j.kotlin.cachedLoggerOf +import org.w3c.dom.Document +import java.io.File +import java.io.IOException +import java.net.MalformedURLException + +/** + * Information about available NeoForge loader versions in correlation to Minecraft versions. + * + * @param loaderManifest Node containing information about available NeoForge versions. + * @param utilities Commonly used utilities across ServerPackCreator. + * @param minecraftMeta Meta for retroactively updating the previously passed meta. + * + * @author Griefed + */ +internal class NeoForgeLoader( + private val loaderManifest: File, + private val utilities: Utilities, + private val minecraftMeta: MinecraftMeta +) { + private val log = cachedLoggerOf(this.javaClass) + val minecraftVersions: MutableList = ArrayList(100) + val neoForgeVersions: MutableList = ArrayList(100) + private val version = "version" + + /** + * 1-n Minecraft version to NeoForge versions. + * * `key`: Minecraft version. + * * `value`: List of NeoForge versions for said Minecraft versions. + */ + val versionMeta: HashMap> = HashMap(200) + + /** + * 1-1 NeoForge version to Minecraft version + * * `key`: NeoForge version. + * * `value`: Minecraft version for said NeoForge version. + */ + val neoForgeToMinecraftMeta: HashMap = HashMap(200) + + /** + * 1-1 Minecraft + NeoForge version combination to [NeoForgeInstance] + * * `key`: Minecraft version + NeoForge version. + * + * Example: + * * `1.18.2-40.0.44` + * + `value`: The [NeoForgeInstance] for said Minecraft and NeoForge version combination. + */ + val instanceMeta: HashMap = HashMap(200) + + /** + * Update the available NeoForge loader information. + * + * @author Griefed + */ + @Throws(IOException::class) + fun update() { + minecraftVersions.clear() + neoForgeVersions.clear() + versionMeta.clear() + neoForgeToMinecraftMeta.clear() + instanceMeta.clear() + + val document: Document = utilities.xmlUtilities.getXml(loaderManifest) + val elements = document.getElementsByTagName(version) + val neoForgeVersionsForMCVer: MutableList = ArrayList(100) + for (i in 0 until elements.length) { + val node = elements.item(i) + val children = node.childNodes + val item = children.item(0) + val combination = item.nodeValue.split("-") + val mcVersion = combination[0] + val neoForgeVersion = combination[1] + + if (!minecraftVersions.contains(mcVersion)) { + minecraftVersions.add(mcVersion) + } + neoForgeVersions.add(neoForgeVersion) + neoForgeVersionsForMCVer.add(neoForgeVersion) + try { + val neoForgeInstance = NeoForgeInstance( + mcVersion, + neoForgeVersion, + minecraftMeta + ) + instanceMeta["$mcVersion-$neoForgeVersion"] = neoForgeInstance + neoForgeToMinecraftMeta[neoForgeVersion] = mcVersion + } catch (ex: MalformedURLException) { + + // Well, in THEORY this should never be thrown, so we don't need to bother + // with a thorough error message + log.debug( + "Could not create NeoForge instance for Minecraft $mcVersion and NeoForge $neoForgeVersion.", + ex + ) + } catch (ex: NoSuchElementException) { + log.debug( + "Could not create NeoForge instance for Minecraft $mcVersion and NeoForge $neoForgeVersion.", + ex + ) + } + versionMeta[mcVersion] = neoForgeVersionsForMCVer + } + } +} \ No newline at end of file diff --git a/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/neoforge/NeoForgeMeta.kt b/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/neoforge/NeoForgeMeta.kt new file mode 100644 index 000000000..db2efc507 --- /dev/null +++ b/serverpackcreator-api/src/jvmMain/kotlin/de/griefed/serverpackcreator/api/versionmeta/neoforge/NeoForgeMeta.kt @@ -0,0 +1,391 @@ +/* Copyright (C) 2023 Griefed + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * The full license can be found at https:github.com/Griefed/ServerPackCreator/blob/main/LICENSE + */ +package de.griefed.serverpackcreator.api.versionmeta.neoforge + +import de.griefed.serverpackcreator.api.utilities.common.Utilities +import de.griefed.serverpackcreator.api.utilities.common.createDirectories +import de.griefed.serverpackcreator.api.versionmeta.minecraft.MinecraftMeta +import java.io.File +import java.io.IOException +import java.util.* + +/** + * NeoForge meta containing information about available NeoForge releases. + * + * @param neoForgeManifest The manifest from which to acquire version information. + * @param utilities Commonly used utilities across ServerPackCreator. + * + * @author Griefed + */ +@Suppress("unused") +actual class NeoForgeMeta actual constructor( + private val neoForgeManifest: File, + private val utilities: Utilities, + installerCacheDirectory: File +) { + private var neoForgeLoader: NeoForgeLoader? = null + private val installerDirectory: File = File(installerCacheDirectory, "neoforge") + + init { + installerDirectory.createDirectories(create = true, directory = true) + } + + /** + * Update this instances [NeoForgeLoader] with new information. Usually called after the NeoForge + * manifest has been refreshed. + * + * @param injectedMinecraftMeta Minecraft manifest file. + * @throws IOException if the manifest could not be parsed into a + * [com.fasterxml.jackson.databind.JsonNode]. + * @author Griefed + */ + @Throws(IOException::class) + fun initialize(injectedMinecraftMeta: MinecraftMeta) { + if (neoForgeLoader == null) { + neoForgeLoader = NeoForgeLoader(neoForgeManifest, utilities, injectedMinecraftMeta) + } + } + + /** + * Update this instances [NeoForgeLoader] with new information. Usually called after the NeoForge + * manifest has been refreshed. + * + * @throws IOException if the manifest could not be parsed into a + * [com.fasterxml.jackson.databind.JsonNode]. + * @author Griefed + */ + @Throws(IOException::class) + fun update() = neoForgeLoader!!.update() + + /** + * Check whether the given Minecraft and NeoForge versions are valid/supported/available. + * + * @param minecraftVersion Minecraft version. + * @param neoForgeVersion NeoForge version. + * @return `true` if the given Minecraft and NeoForge versions are valid/supported/available. + * @author Griefed + */ + actual fun isNeoForgeAndMinecraftCombinationValid(minecraftVersion: String, neoForgeVersion: String) = + isMinecraftVersionSupported(minecraftVersion) && isNeoForgeVersionValid(neoForgeVersion) + + /** + * Check whether a given Minecraft version is valid/supported/available. + * + * @param minecraftVersion Minecraft version. + * @return `true` if the given Minecraft version is valid/supported/available. + * @author Griefed + */ + actual fun isMinecraftVersionSupported(minecraftVersion: String) = + Optional.ofNullable(neoForgeLoader!!.versionMeta[minecraftVersion]).isPresent + + /** + * Check whether a given NeoForge version is valid/supported/available. + * + * @param neoForgeVersion NeoForge version. + * @return `true` if the given NeoForge version is valid/supported/available. + * @author Griefed + */ + actual fun isNeoForgeVersionValid(neoForgeVersion: String) = + Optional.ofNullable(neoForgeLoader!!.neoForgeToMinecraftMeta[neoForgeVersion]).isPresent + + /** + * Check whether NeoForge is available for a given NeoForge- and Minecraft version. + * + * @param minecraftVersion Minecraft version. + * @param neoForgeVersion NeoForge version. + * @return `true` if NeoForge is available for the given NeoForge- and Minecraft version. + * @author Griefed + */ + actual fun isNeoForgeInstanceAvailable(minecraftVersion: String, neoForgeVersion: String) = + getNeoForgeInstance(minecraftVersion, neoForgeVersion).isPresent + + /** + * Get a [NeoForgeInstance] for a given Minecraft and NeoForge version, wrapped in an + * [Optional]. + * + * @param minecraftVersion Minecraft version. + * @param neoForgeVersion NeoForge version. + * @return NeoForge instance for the given Minecraft and NeoForge version, wrapped in an + * [Optional] + * @author Griefed + */ + fun getNeoForgeInstance(minecraftVersion: String, neoForgeVersion: String) = + Optional.ofNullable(neoForgeLoader!!.instanceMeta["$minecraftVersion-$neoForgeVersion"]) + + /** + * Check whether NeoForge is available for a given NeoForge version + * + * @param neoForgeVersion NeoForge version. + * @return `true` if NeoForge is available for the given NeoForge version. + * @author Griefed + */ + actual fun isNeoForgeInstanceAvailable(neoForgeVersion: String) = getNeoForgeInstance(neoForgeVersion).isPresent + + /** + * Get a [NeoForgeInstance] for a given NeoForge version, wrapped in an [Optional]. + * + * @param neoForgeVersion NeoForge version. + * @return NeoForge instance for the given NeoForge version, wrapped in an [Optional] + * @author Griefed + */ + fun getNeoForgeInstance(neoForgeVersion: String) = + if (!isNeoForgeVersionValid(neoForgeVersion)) { + Optional.empty() + } else if (minecraftVersion(neoForgeVersion).isPresent) { + val mcVersion = minecraftVersion(neoForgeVersion).get() + getNeoForgeInstance(mcVersion, neoForgeVersion) + } else { + Optional.empty() + } + + /** + * Get a list of all available [NeoForgeInstance] for a given Minecraft version, wrapped in an + * [Optional] + * + * @param minecraftVersion Minecraft version. + * @return NeoForge instance-list for the given Minecraft version. + * @author Griefed + */ + fun getNeoForgeInstances(minecraftVersion: String): Optional> { + val list: MutableList = ArrayList(100) + val instance = neoForgeLoader!!.versionMeta[minecraftVersion] + return if (Optional.ofNullable(instance).isPresent) { + for (version in instance!!) { + val specificInstance = neoForgeLoader!!.instanceMeta["$minecraftVersion-$version"] + if (specificInstance != null) { + list.add(specificInstance) + } + } + Optional.of(list) + } else { + Optional.empty() + } + } + + /** + * Latest NeoForge version for a given Minecraft version, wrapped in [Optional] + * + * @param minecraftVersion Minecraft version. + * @return Latest NeoForge version for the given Minecraft version, wrapped in an [Optional] + * @author Griefed + */ + actual fun newestNeoForgeVersion(minecraftVersion: String) = + if (!isMinecraftVersionSupported(minecraftVersion)) { + Optional.empty() + } else if (supportedNeoForgeVersionsAscending(minecraftVersion).isPresent) { + val latestMCVersion = supportedNeoForgeVersionsAscending(minecraftVersion).get().size - 1 + val supported = supportedNeoForgeVersionsAscending(minecraftVersion).get() + Optional.of(supported[latestMCVersion]) + } else { + Optional.empty() + } + + /** + * Oldest NeoForge version for a given Minecraft version, wrapped in [Optional] + * + * @param minecraftVersion Minecraft version. + * @return Oldest NeoForge version for the given Minecraft version, wrapped in [Optional] + * @author Griefed + */ + actual fun oldestNeoForgeVersion(minecraftVersion: String) = + if (!isMinecraftVersionSupported(minecraftVersion)) { + Optional.empty() + } else if (supportedNeoForgeVersionsAscending(minecraftVersion).isPresent) { + val supported = supportedNeoForgeVersionsAscending(minecraftVersion).get() + Optional.ofNullable(supported[0]) + } else { + Optional.empty() + } + + /** + * Get the list of available NeoForge versions, in ascending order. + * + * @return List of available NeoForge versions. + * @author Griefed + */ + actual fun neoForgeVersionsAscending() = neoForgeLoader!!.neoForgeVersions + + /** + * Get the list of available NeoForge versions, in descending order. + * + * @return List of available NeoForge versions. + * @author Griefed + */ + actual fun neoForgeVersionsDescending() = neoForgeVersionsAscending().reversed() + + /** + * Get the array of available NeoForge versions, in ascending order. + * + * @return Array of available NeoForge versions. + * @author Griefed + */ + actual fun neoForgeVersionsAscendingArray() = neoForgeVersionsAscending().toTypedArray() + + /** + * Get the array of available NeoForge versions, in descending order. + * + * @return Array of available NeoForge versions. + * @author Griefed + */ + actual fun neoForgeVersionsDescendingArray() = neoForgeVersionsDescending().toTypedArray() + + /** + * Get a list of available NeoForge version for a given Minecraft version in ascending order. + * + * @param minecraftVersion Minecraft version. + * @return List of available NeoForge versions for the given Minecraft version in ascending order. + * @author Griefed + */ + actual fun supportedNeoForgeVersionsAscending(minecraftVersion: String) = + Optional.ofNullable(neoForgeLoader?.versionMeta?.get(minecraftVersion)) + + /** + * Get a list of available NeoForge version for a given Minecraft version in descending order. + * + * @param minecraftVersion Minecraft version. + * @return List of available NeoForge versions for the given Minecraft version in descending order. + * @author Griefed + */ + actual fun supportedNeoForgeVersionsDescending(minecraftVersion: String) = + if (!isMinecraftVersionSupported(minecraftVersion)) { + Optional.empty() + } else { + val supported = supportedNeoForgeVersionsAscending(minecraftVersion).get() + Optional.ofNullable(supported.reversed()) + } + + + /** + * Get an array of available NeoForge version for a given Minecraft version, in ascending order, + * wrapped in an [Optional]. + * + * @param minecraftVersion Minecraft version. + * @return Array of available NeoForge versions for the given Minecraft version, in ascending order, + * wrapped in an [Optional] + * @author Griefed + */ + actual fun supportedNeoForgeVersionsAscendingArray(minecraftVersion: String) = + if (!isMinecraftVersionSupported(minecraftVersion)) { + Optional.empty() + } else { + val supported = supportedNeoForgeVersionsAscending(minecraftVersion).get() + Optional.of( + supported.toTypedArray() + ) + } + + /** + * Get an array of available NeoForge version for a given Minecraft version, in descending order, + * wrapped in an [Optional]. + * + * @param minecraftVersion Minecraft version. + * @return Array of available NeoForge versions for the given Minecraft version, in descending order, + * wrapped in an [Optional] + * @author Griefed + */ + actual fun supportedNeoForgeVersionsDescendingArray(minecraftVersion: String) = + if (!isMinecraftVersionSupported(minecraftVersion)) { + Optional.empty() + } else { + val supported = supportedNeoForgeVersionsDescending(minecraftVersion).get() + Optional.of(supported.toTypedArray()) + } + + /** + * Get the Minecraft version for a given NeoForge version, wrapped in an [Optional]. + * + * @param neoForgeVersion NeoForge version. + * @return Minecraft version for the given Neo version, wrapped in an [Optional]. + * @author Griefed + */ + actual fun minecraftVersion(neoForgeVersion: String) = + Optional.ofNullable(neoForgeLoader!!.neoForgeToMinecraftMeta[neoForgeVersion]) + + /** + * Get the list of NeoForge supported Minecraft versions, in ascending order. + * + * @return List of NeoForge supported Minecraft versions, in ascending order. + * @author Griefed + */ + actual fun supportedMinecraftVersionsAscending() = neoForgeLoader!!.minecraftVersions + + /** + * Get the list of NeoForge supported Minecraft versions, in descending order. + * + * @return List of NeoForge supported Minecraft versions, in descending order. + * @author Griefed + */ + actual fun supportedMinecraftVersionsDescending() = supportedMinecraftVersionsAscending().reversed() + + /** + * Get the array of NeoForge supported Minecraft versions, in ascending order. + * + * @return Array of NeoForge supported Minecraft versions, in ascending order. + * @author Griefed + */ + actual fun supportedMinecraftVersionsAscendingArray() = supportedMinecraftVersionsAscending().toTypedArray() + + /** + * Get the array of NeoForge supported Minecraft versions, in descending order. + * + * @return Array of NeoForge supported Minecraft versions, in descending order. + * @author Griefed + */ + actual fun supportedMinecraftVersionsDescendingArray() = supportedMinecraftVersionsDescending().toTypedArray() + + /** + * Get the NeoForge server installer URL for a given NeoForge version, wrapped in an [Optional]. + * + * @param neoForgeVersion NeoForge version. + * @return NeoForge server installer URL for the given NeoForge version, wrapped in an [Optional]. + * @author Griefed + */ + actual fun installerUrl(neoForgeVersion: String) = + if (isNeoForgeVersionValid(neoForgeVersion) && getNeoForgeInstance(neoForgeVersion).isPresent) { + val instance = getNeoForgeInstance(neoForgeVersion).get() + Optional.of(instance.installerUrl) + } else { + Optional.empty() + } + + + /** + * Installer file for the specified [neoForgeVersion] and [minecraftVersion] version, wrapped in an [Optional], so you + * can check whether it is available first. + * @author Griefed + */ + actual fun installerFor(neoForgeVersion: String, minecraftVersion: String) = + if (isNeoForgeInstanceAvailable(minecraftVersion, neoForgeVersion)) { + val destination = File(installerDirectory, "$neoForgeVersion-$minecraftVersion.jar") + if (!destination.isFile) { + val url = installerUrl(neoForgeVersion).get() + val downloaded = utilities.webUtilities.downloadFile(destination, url) + if (downloaded) { + Optional.of(destination) + } else { + Optional.empty() + } + } else { + Optional.of(destination) + } + } else { + Optional.empty() + } +} \ No newline at end of file diff --git a/serverpackcreator-api/src/jvmMain/resources/de/griefed/resources/server_files/default_template.ps1 b/serverpackcreator-api/src/jvmMain/resources/de/griefed/resources/server_files/default_template.ps1 index 2636e5263..ac7a98650 100644 --- a/serverpackcreator-api/src/jvmMain/resources/de/griefed/resources/server_files/default_template.ps1 +++ b/serverpackcreator-api/src/jvmMain/resources/de/griefed/resources/server_files/default_template.ps1 @@ -200,6 +200,76 @@ Function global:SetupForge } } +# If modloader = NeoForge, run NeoForge-specific checks +Function global:SetupNeoForge +{ + "" + "Running NeoForge checks and setup..." + $ForgeInstallerUrl = "https://maven.neoforged.net/net/neoforged/forge/${MinecraftVersion}-${ModLoaderVersion}/forge-${MinecraftVersion}-${ModLoaderVersion}-installer.jar" + $ForgeJarLocation = "do_not_manually_edit" + $MINOR = ${MinecraftVersion}.Split(".") + + if ($MINOR[1] -le 16) + { + $ForgeJarLocation = "forge.jar" + $script:LauncherJarLocation = "forge.jar" + $script:MinecraftServerJarLocation = "minecraft_server.${MinecraftVersion}.jar" + $script:ServerRunCommand = "-Dlog4j2.formatMsgNoLookups=true ${JavaArgs} -jar ${LauncherJarLocation} nogui" + } + else + { + $ForgeJarLocation = "libraries/net/neoforged/forge/${MinecraftVersion}-${ModLoaderVersion}/forge-${MinecraftVersion}-${ModLoaderVersion}-server.jar" + $script:MinecraftServerJarLocation = "libraries/net/minecraft/server/${MinecraftVersion}/server-${MinecraftVersion}.jar" + $script:ServerRunCommand = "-Dlog4j2.formatMsgNoLookups=true @user_jvm_args.txt @libraries/net/neoforged/forge/${MinecraftVersion}-${ModLoaderVersion}/win_args.txt nogui" + + Write-Host "Generating user_jvm_args.txt from variables..." + Write-Host "Edit JAVA_ARGS in your variables.txt. Do not edit user_jvm_args.txt directly!" + Write-Host "Manually made changes to user_jvm_args.txt will be lost in the nether!" + + DeleteFileSilently 'user_jvm_args.txt' + + "# Xmx and Xms set the maximum and minimum RAM usage, respectively.`n" + + "# They can take any number, followed by an M or a G.`n" + + "# M means Megabyte, G means Gigabyte.`n" + + "# For example, to set the maximum to 3GB: -Xmx3G`n" + + "# To set the minimum to 2.5GB: -Xms2500M`n" + + "# A good default for a modded server is 4GB.`n" + + "# Uncomment the next line to set it.`n" + + "# -Xmx4G`n" + + "${script:JavaArgs}" | Out-File user_jvm_args.txt -encoding utf8 + } + + if ((DownloadIfNotExists "${ForgeJarLocation}" "neoforge-installer.jar" "${ForgeInstallerUrl}")) + { + "NeoForge Installer downloaded. Installing..." + RunJavaCommand "-jar neoforge-installer.jar --installServer" + + if ($MINOR[1] -gt 16) + { + DeleteFileSilently 'run.bat' + DeleteFileSilently 'run.sh' + } + else + { + "Renaming forge-${MinecraftVersion}-${ModLoaderVersion}.jar to forge.jar" + Move-Item "forge-${MinecraftVersion}-${ModLoaderVersion}.jar" 'forge.jar' + } + + if ((Test-Path -Path "${ForgeJarLocation}" -PathType Leaf)) + { + DeleteFileSilently 'neoforge-installer.jar' + DeleteFileSilently 'neoforge-installer.jar.log' + "Installation complete. forge-installer.jar deleted." + } + else + { + DeleteFileSilently 'neoforge-installer.jar' + "Something went wrong during the server installation. Please try again in a couple of minutes and check your internet connection." + Crash + } + } +} + # If modloader = Fabric, run Fabric-specific checks Function global:SetupFabric { @@ -408,6 +478,10 @@ switch ( ${ModLoader} ) { SetupForge } + NeoForge + { + SetupNeoForge + } Fabric { SetupFabric diff --git a/serverpackcreator-api/src/jvmMain/resources/de/griefed/resources/server_files/default_template.sh b/serverpackcreator-api/src/jvmMain/resources/de/griefed/resources/server_files/default_template.sh index f4166ef88..978b13743 100644 --- a/serverpackcreator-api/src/jvmMain/resources/de/griefed/resources/server_files/default_template.sh +++ b/serverpackcreator-api/src/jvmMain/resources/de/griefed/resources/server_files/default_template.sh @@ -121,6 +121,69 @@ setup_forge() { fi } +# If modloader = NeoForge, run NeoForge-specific checks +setup_neoforge() { + echo "" + echo "Running NeoForge checks and setup..." + + FORGE_INSTALLER_URL="https://maven.neoforged.net/net/neoforged/forge/${MINECRAFT_VERSION}-${MODLOADER_VERSION}/forge-${MINECRAFT_VERSION}-${MODLOADER_VERSION}-installer.jar" + + FORGE_JAR_LOCATION="do_not_manually_edit" + IFS="." read -ra MINOR <<<"${MINECRAFT_VERSION}" + + if [[ ${MINOR[1]} -le 16 ]]; then + FORGE_JAR_LOCATION="forge.jar" + LAUNCHER_JAR_LOCATION="forge.jar" + MINECRAFT_SERVER_JAR_LOCATION="minecraft_server.${MINECRAFT_VERSION}.jar" + SERVER_RUN_COMMAND="-Dlog4j2.formatMsgNoLookups=true ${JAVA_ARGS} -jar ${LAUNCHER_JAR_LOCATION} nogui" + else + FORGE_JAR_LOCATION="libraries/net/neoforged/forge/${MINECRAFT_VERSION}-${MODLOADER_VERSION}/forge-${MINECRAFT_VERSION}-${MODLOADER_VERSION}-server.jar" + MINECRAFT_SERVER_JAR_LOCATION="libraries/net/minecraft/server/${MINECRAFT_VERSION}/server-${MINECRAFT_VERSION}.jar" + SERVER_RUN_COMMAND="-Dlog4j2.formatMsgNoLookups=true @user_jvm_args.txt @libraries/net/neoforged/forge/${MINECRAFT_VERSION}-${MODLOADER_VERSION}/unix_args.txt nogui" + + echo "Generating user_jvm_args.txt from variables..." + echo "Edit JAVA_ARGS in your variables.txt. Do not edit user_jvm_args.txt directly!" + echo "Manually made changes to user_jvm_args.txt will be lost in the nether!" + rm -f user_jvm_args.txt + { + echo "# Xmx and Xms set the maximum and minimum RAM usage, respectively." + echo "# They can take any number, followed by an M or a G." + echo "# M means Megabyte, G means Gigabyte." + echo "# For example, to set the maximum to 3GB: -Xmx3G" + echo "# To set the minimum to 2.5GB: -Xms2500M" + echo "# A good default for a modded server is 4GB." + echo "# Uncomment the next line to set it." + echo "# -Xmx4G" + echo "${JAVA_ARGS}" + } >>user_jvm_args.txt + fi + + if [[ $(downloadIfNotExist "${FORGE_JAR_LOCATION}" "neoforge-installer.jar" "${FORGE_INSTALLER_URL}") == "true" ]]; then + + echo "NeoForge Installer downloaded. Installing..." + runJavaCommand "-jar neoforge-installer.jar --installServer" + + if [[ ${MINOR[1]} -gt 16 ]]; then + rm -f run.bat + rm -f run.sh + else + echo "Renaming forge-${MINECRAFT_VERSION}-${MODLOADER_VERSION}.jar to forge.jar" + mv forge-"${MINECRAFT_VERSION}"-"${MODLOADER_VERSION}".jar forge.jar + fi + + if [[ -s "${FORGE_JAR_LOCATION}" ]]; then + rm -f neoforge-installer.jar + rm -f neoforge-installer.jar.log + echo "Installation complete. neoforge-installer.jar deleted." + else + rm -f neoforge-installer.jar + echo "Something went wrong during the server installation. Please try again in a couple of minutes and check your internet connection." + crash + fi + + fi +} + # If modloader = Fabric, run Fabric-specific checks setup_fabric() { echo "" @@ -274,6 +337,10 @@ case ${MODLOADER} in setup_forge ;; + "NeoForge") + setup_forge + ;; + "Fabric") setup_fabric ;; diff --git a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/configs/ConfigEditor.kt b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/configs/ConfigEditor.kt index c78959c37..c953aa0d6 100644 --- a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/configs/ConfigEditor.kt +++ b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/configs/ConfigEditor.kt @@ -447,6 +447,7 @@ class ConfigEditor( when (modloader) { "Fabric" -> modloaders.selectedIndex = 0 "Forge" -> modloaders.selectedIndex = 1 + "NeoForge" -> modloaders.selectedIndex = 4 "Quilt" -> modloaders.selectedIndex = 2 "LegacyFabric" -> modloaders.selectedIndex = 3 } @@ -955,6 +956,7 @@ class ConfigEditor( 1 -> updateForgeModel(minecraftVersion) 2 -> updateQuiltModel(minecraftVersion) 3 -> updateLegacyFabricModel(minecraftVersion) + 4 -> updateNeoForgeModel(minecraftVersion) else -> { log.error("Invalid modloader selected.") } @@ -1008,6 +1010,25 @@ class ConfigEditor( } } + /** + * @author Griefed + */ + private fun updateNeoForgeModel(minecraftVersion: String = minecraftVersions.selectedItem!!.toString()) { + if (apiWrapper.versionMeta!!.neoForge.supportedNeoForgeVersionsDescendingArray(minecraftVersion).isPresent) { + setModloaderVersions( + DefaultComboBoxModel( + apiWrapper.versionMeta!!.neoForge.supportedNeoForgeVersionsDescendingArray(minecraftVersion).get() + ) + ) + } else { + setModloaderVersions( + noVersions, + guiProps.errorIcon, + Gui.configuration_log_error_minecraft_modloader(getMinecraftVersion(), getModloader()) + ) + } + } + /** * @author Griefed */ diff --git a/serverpackcreator-web/src/main/kotlin/de/griefed/serverpackcreator/web/BeanConfiguration.kt b/serverpackcreator-web/src/main/kotlin/de/griefed/serverpackcreator/web/BeanConfiguration.kt index 525d03ced..66346f59e 100644 --- a/serverpackcreator-web/src/main/kotlin/de/griefed/serverpackcreator/web/BeanConfiguration.kt +++ b/serverpackcreator-web/src/main/kotlin/de/griefed/serverpackcreator/web/BeanConfiguration.kt @@ -156,6 +156,11 @@ class BeanConfiguration @Autowired constructor() { return apiWrapper().apiProperties.forgeVersionManifest } + @Bean + fun neoForgeManifest(): File { + return apiWrapper().apiProperties.neoForgeVersionManifest + } + @Bean fun fabricManifest(): File { return apiWrapper().apiProperties.fabricVersionManifest