diff --git a/.runConfigurations/Build JPackager Installer.run.xml b/.runConfigurations/Build JPackager Installer.run.xml index fa370cee0ea341f8309daed7e5e80836834aace5..8ff6f807b74db8aff9492258ec9290676f0caab1 100644 --- a/.runConfigurations/Build JPackager Installer.run.xml +++ b/.runConfigurations/Build JPackager Installer.run.xml @@ -4,7 +4,7 @@ <option name="executionName" /> <option name="externalProjectPath" value="$PROJECT_DIR$/serverpackcreator-app" /> <option name="externalSystemIdString" value="GRADLE" /> - <option name="scriptParameters" value="--full-stacktrace --info" /> + <option name="scriptParameters" value="--full-stacktrace --info -x :serverpackcreator-api:test" /> <option name="taskDescriptions"> <list /> </option> @@ -18,6 +18,7 @@ <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess> <ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess> <DebugAllEnabled>false</DebugAllEnabled> + <RunAsTest>false</RunAsTest> <method v="2" /> </configuration> </component> \ No newline at end of file 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 801bf50c368e74438be75e1b278549df6e615723..72b1ce081653fb820ccddff26b5000d008b0269c 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 @@ -60,9 +60,9 @@ abstract class Configuration<F, P> { */ abstract fun checkConfiguration( configFile: F, - packConfig: PackConfig = PackConfig(), - configCheck: ConfigCheck = ConfigCheck(), - quietCheck: Boolean = false + packConfig: PackConfig, + configCheck: ConfigCheck, + quietCheck: Boolean ): ConfigCheck /** @@ -84,8 +84,8 @@ abstract class Configuration<F, P> { */ abstract fun checkConfiguration( packConfig: PackConfig, - configCheck: ConfigCheck = ConfigCheck(), - quietCheck: Boolean = false + configCheck: ConfigCheck, + quietCheck: Boolean ): ConfigCheck /** @@ -109,7 +109,7 @@ abstract class Configuration<F, P> { * specified, but the file was not found. * @author Griefed */ - abstract fun checkIconAndProperties(iconOrPropertiesPath: String = ""): Boolean + abstract fun checkIconAndProperties(iconOrPropertiesPath: String): Boolean /** * If the in the configuration specified modpack dir is an existing directory, checks are made for @@ -123,7 +123,7 @@ abstract class Configuration<F, P> { * @return `true` if an error is found during configuration check. * @author Griefed */ - abstract fun isDir(packConfig: PackConfig, configCheck: ConfigCheck = ConfigCheck()): ConfigCheck + abstract fun isDir(packConfig: PackConfig, configCheck: ConfigCheck): ConfigCheck /** * Checks the specified ZIP-archive for validity. In order for a modpack ZIP-archive to be @@ -137,7 +137,7 @@ abstract class Configuration<F, P> { * @return `false` when no errors were encountered. * @author Griefed */ - abstract fun isZip(packConfig: PackConfig, configCheck: ConfigCheck = ConfigCheck()): ConfigCheck + abstract fun isZip(packConfig: PackConfig, configCheck: ConfigCheck): ConfigCheck /** * Checks whether either Forge or Fabric were specified as the modloader. @@ -146,7 +146,7 @@ abstract class Configuration<F, P> { * @return `true` if the specified modloader is either Forge or Fabric. False if neither. * @author Griefed */ - abstract fun checkModloader(modloader: String, configCheck: ConfigCheck = ConfigCheck()): ConfigCheck + abstract fun checkModloader(modloader: String, configCheck: ConfigCheck): ConfigCheck /** * Check the given Minecraft and modloader versions for the specified modloader. @@ -161,7 +161,7 @@ abstract class Configuration<F, P> { * @author Griefed */ abstract fun checkModloaderVersion( - modloader: String, modloaderVersion: String, minecraftVersion: String, configCheck: ConfigCheck = ConfigCheck() + modloader: String, modloaderVersion: String, minecraftVersion: String, configCheck: ConfigCheck ): ConfigCheck /** @@ -248,8 +248,8 @@ abstract class Configuration<F, P> { abstract fun checkInclusions( inclusions: MutableList<InclusionSpecification>, modpackDir: String, - configCheck: ConfigCheck = ConfigCheck(), - printLog: Boolean = true + configCheck: ConfigCheck, + printLog: Boolean ): ConfigCheck /** @@ -259,7 +259,7 @@ abstract class Configuration<F, P> { * @param pathToZip Path to the ZIP-file to check. * @author Griefed */ - abstract fun checkZipArchive(pathToZip: String, configCheck: ConfigCheck = ConfigCheck()): ConfigCheck + abstract fun checkZipArchive(pathToZip: String, configCheck: ConfigCheck): ConfigCheck /** * Update the destination to which the ZIP-archive will the extracted to, based on whether a @@ -298,7 +298,7 @@ abstract class Configuration<F, P> { abstract fun checkManifests( destination: String, packConfig: PackConfig, - configCheck: ConfigCheck = ConfigCheck() + configCheck: ConfigCheck ): String? /** @@ -505,8 +505,8 @@ abstract class Configuration<F, P> { */ abstract fun checkModpackDir( modpackDir: String, - configCheck: ConfigCheck = ConfigCheck(), - printLog: Boolean = true + configCheck: ConfigCheck, + printLog: Boolean ): ConfigCheck /** diff --git a/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/ConfigurationHandler.kt b/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/ConfigurationHandler.kt index 3ffb1496e3a0e5e1b70ed375aefee964c1b691bd..360d862cf8c9599187e0a9988f73e5a83de16018 100644 --- a/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/ConfigurationHandler.kt +++ b/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/ConfigurationHandler.kt @@ -32,18 +32,18 @@ import de.griefed.serverpackcreator.api.utilities.File * @author Griefed */ expect class ConfigurationHandler { - fun checkConfiguration(configFile: File, packConfig: PackConfig, configCheck: ConfigCheck = ConfigCheck(), quietCheck: Boolean = false): ConfigCheck - fun checkConfiguration(packConfig: PackConfig, configCheck: ConfigCheck = ConfigCheck(), quietCheck: Boolean = false): ConfigCheck + fun checkConfiguration(configFile: File, packConfig: PackConfig = PackConfig(), configCheck: ConfigCheck = ConfigCheck(), quietCheck: Boolean = false): ConfigCheck + fun checkConfiguration(packConfig: PackConfig = PackConfig(), configCheck: ConfigCheck = ConfigCheck(), quietCheck: Boolean = false): ConfigCheck fun isDir(packConfig: PackConfig, configCheck: ConfigCheck = ConfigCheck()): ConfigCheck fun isZip(packConfig: PackConfig, configCheck: ConfigCheck = ConfigCheck()): ConfigCheck fun checkModloaderVersion(modloader: String, modloaderVersion: String, minecraftVersion: String, configCheck: ConfigCheck = ConfigCheck()): ConfigCheck - fun checkInclusions(inclusions: MutableList<InclusionSpecification>,modpackDir: String, configCheck: ConfigCheck = ConfigCheck(),printLog: Boolean = true): ConfigCheck + fun checkInclusions(inclusions: MutableList<InclusionSpecification>, modpackDir: String, configCheck: ConfigCheck = ConfigCheck(), printLog: Boolean = true): ConfigCheck fun checkZipArchive(pathToZip: String, configCheck: ConfigCheck = ConfigCheck()): ConfigCheck fun checkManifests(destination: String, packConfig: PackConfig, configCheck: ConfigCheck = ConfigCheck()): String? - fun checkModpackDir(modpackDir: String, configCheck: ConfigCheck = ConfigCheck(), printLog: Boolean): ConfigCheck - fun checkModloader(modloader: String,configCheck: ConfigCheck): ConfigCheck + fun checkModpackDir(modpackDir: String, configCheck: ConfigCheck = ConfigCheck(), printLog: Boolean = true): ConfigCheck + fun checkModloader(modloader: String,configCheck: ConfigCheck = ConfigCheck()): ConfigCheck - fun checkIconAndProperties(iconOrPropertiesPath: String): Boolean + fun checkIconAndProperties(iconOrPropertiesPath: String = ""): Boolean fun ensureScriptSettingsDefaults(packConfig: PackConfig) fun sanitizeLinks(packConfig: PackConfig) 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 6cdd0e8bfe457d206243a6b5ea0d18e8e5ab7994..d819598d93bbe0c02f2e043166e546234d9721b9 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 @@ -33,9 +33,10 @@ abstract class Pack<F, J, out P> { protected val fabric = "^fabric$".toRegex() protected val quilt = "^quilt$".toRegex() protected val legacyFabric = "^legacyfabric$".toRegex() - protected val whitespace = "\\s+".toRegex() + protected val whitespace = "^\\s+$".toRegex() val clientMods: ArrayList<String> = ArrayList(1000) + val modsWhitelist: ArrayList<String> = ArrayList(1000) val inclusions: ArrayList<InclusionSpecification> = ArrayList(100) val scriptSettings = HashMap<String, String>(100) val pluginsConfigs = HashMap<String, ArrayList<CommentedConfig>>(20) @@ -92,12 +93,18 @@ abstract class Pack<F, J, out P> { return pluginsConfigs[pluginId]!! } - fun setClientMods(newClientMods: ArrayList<String>) { + fun setClientMods(newClientMods: MutableList<String>) { clientMods.clear() - newClientMods.removeIf { entry: String -> entry.matches(whitespace) || entry.isEmpty() } + newClientMods.removeIf { entry: String -> entry.isBlank() || entry.matches(whitespace) } clientMods.addAll(newClientMods) } + fun setModsWhitelist(newModsWhitelist: MutableList<String>) { + modsWhitelist.clear() + newModsWhitelist.removeIf { entry: String -> entry.isBlank() || entry.matches(whitespace) } + modsWhitelist.addAll(newModsWhitelist) + } + fun setInclusions(newCopyDirs: ArrayList<InclusionSpecification>) { inclusions.clear() inclusions.addAll(newCopyDirs) @@ -111,6 +118,7 @@ abstract class Pack<F, J, out P> { override fun toString(): String { return "Pack(" + " clientMods=$clientMods," + + " whiteList=$modsWhitelist," + " copyDirs=$inclusions," + " scriptSettings=$scriptSettings," + " pluginsConfigs=$pluginsConfigs," + diff --git a/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/PackConfig.kt b/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/PackConfig.kt index 8de7403c5665ca6fcda569a245d6d957bd3d9b59..ae5694ce1ecd1559c7f8df1d728a17b0c602613f 100644 --- a/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/PackConfig.kt +++ b/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/PackConfig.kt @@ -43,6 +43,7 @@ import de.griefed.serverpackcreator.api.utilities.File expect open class PackConfig { val clientMods: ArrayList<String> + val modsWhitelist: ArrayList<String> val inclusions: ArrayList<InclusionSpecification> val scriptSettings: HashMap<String, String> val pluginsConfigs: HashMap<String, ArrayList<CommentedConfig>> @@ -65,6 +66,7 @@ expect open class PackConfig { * Construct a new configuration model with custom values. * * @param clientMods List of clientside mods to exclude from the server pack. + * @param whitelist List of mods to include if present, regardless whether a match was found through [clientMods] * @param copyDirs List of directories and/or files to include in the server pack. * @param modpackDir The path to the modpack. * @param minecraftVersion The Minecraft version the modpack uses. @@ -84,6 +86,7 @@ expect open class PackConfig { */ constructor( clientMods: List<String>, + whitelist: List<String>, copyDirs: List<InclusionSpecification>, modpackDir: String, minecraftVersion: String, diff --git a/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/ServerPack.kt b/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/ServerPack.kt index 7838a835c407b53130043c8912831835e655b6e6..facd12eecb3c77df90872bfb6dbc83c57e97b16a 100644 --- a/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/ServerPack.kt +++ b/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/ServerPack.kt @@ -101,6 +101,7 @@ abstract class ServerPack<F, TS, TF> { packConfig.modpackDir, packConfig.inclusions, packConfig.clientMods, + packConfig.modsWhitelist, packConfig.minecraftVersion, getServerPackDestination(packConfig), packConfig.modloader @@ -211,6 +212,7 @@ abstract class ServerPack<F, TS, TF> { modpackDir: String, inclusions: ArrayList<InclusionSpecification>, clientMods: List<String>, + whitelist: List<String>, minecraftVersion: String, destination: String, modloader: String @@ -314,6 +316,7 @@ abstract class ServerPack<F, TS, TF> { * @param modsDir The mods-directory of the modpack of which to generate a list of * all its contents. * @param userSpecifiedClientMods A list of all clientside-only mods. + * @param userSpecifiedWhitelist A list of mods to include regardless if a match was found in [userSpecifiedClientMods]. * @param minecraftVersion The Minecraft version the modpack uses. When the modloader is * Forge, this determines whether Annotations or Tomls are * scanned. @@ -322,7 +325,11 @@ abstract class ServerPack<F, TS, TF> { * @author Griefed */ abstract fun getModsToInclude( - modsDir: String, userSpecifiedClientMods: List<String>, minecraftVersion: String, modloader: String + modsDir: String, + userSpecifiedClientMods: List<String>, + userSpecifiedModsWhitelist: List<String>, + minecraftVersion: String, + modloader: String ): List<F> /** @@ -367,6 +374,7 @@ abstract class ServerPack<F, TS, TF> { fun getModsToInclude(packConfig: Pack<*, *, *>) = getModsToInclude( "${packConfig.modpackDir}${File.separator}mods", packConfig.clientMods, + packConfig.modsWhitelist, packConfig.minecraftVersion, packConfig.modloader ) @@ -457,7 +465,7 @@ abstract class ServerPack<F, TS, TF> { * modpack. * @author Griefed */ - abstract fun excludeUserSpecifiedMod(userSpecifiedExclusions: List<String>, modsInModpack: TF) + abstract fun excludeUserSpecifiedMod(userSpecifiedExclusions: List<String>, userSpecifiedModsWhitelist: List<String>, modsInModpack: TF) /** * Walk through the specified directory and add a [ServerPackFile] for every file/folder @@ -484,7 +492,7 @@ abstract class ServerPack<F, TS, TF> { * * @author Griefed */ - abstract fun exclude(userSpecifiedExclusion: String, modsInModpack: TF) + abstract fun exclude(userSpecifiedExclusion: String, userSpecifiedModsWhitelist: List<String>, modsInModpack: TF) /** * Cleans up the server_pack directory by deleting left-over files from modloader installations diff --git a/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/plugins/swinggui/ServerPackConfigTab.kt b/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/plugins/swinggui/ServerPackConfigTab.kt index b9cf48591aeb5378fabcd3076e334fde991f9665..b60961359179ec53ab768d09101dd7aacaef6f37 100644 --- a/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/plugins/swinggui/ServerPackConfigTab.kt +++ b/serverpackcreator-api/src/commonMain/kotlin/de/griefed/serverpackcreator/api/plugins/swinggui/ServerPackConfigTab.kt @@ -35,6 +35,7 @@ import de.griefed.serverpackcreator.api.utilities.File @Suppress("unused") interface ServerPackConfigTab { fun setClientSideMods(entries: MutableList<String>) + fun setWhitelist(entries: MutableList<String>) fun setInclusions(entries: MutableList<InclusionSpecification>) fun setIconInclusionTicked(ticked: Boolean) fun setJavaArguments(javaArguments: String) @@ -52,6 +53,8 @@ interface ServerPackConfigTab { fun getClientSideMods(): String fun getClientSideModsList(): MutableList<String> + fun getWhitelist(): String + fun getWhitelistList(): MutableList<String> fun getInclusions(): List<InclusionSpecification> fun getCurrentConfiguration(): PackConfig fun saveCurrentConfiguration(): 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 ac217a0064b0935dc8fc303e0f81c80074b8b685..a2cf2ff6f13f4b401fd526bbe152047d93adf8b5 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 @@ -32,6 +32,7 @@ import java.io.InputStreamReader import java.net.URL import java.util.* import java.util.prefs.Preferences +import kotlin.collections.ArrayList /** * Base settings of ServerPackCreator, such as working directories, default list of clientside-only @@ -72,6 +73,8 @@ actual class ApiProperties( "de.griefed.serverpackcreator.configuration.fallbackmodslist" private val pConfigurationFallbackModsListRegex = "de.griefed.serverpackcreator.configuration.fallbackmodslist.regex" + private val pConfigurationFallbackModsWhiteList = + "de.griefed.serverpackcreator.configuration.modswhitelist" private val pConfigurationHasteBinServerUrl = "de.griefed.serverpackcreator.configuration.hastebinserver" private val pConfigurationAikarsFlags = @@ -139,6 +142,13 @@ actual class ApiProperties( jarInformation.jarFolder.absoluteFile } + @Suppress("SpellCheckingInspection") + private var fallbackModsWhitelist = TreeSet( + listOf( + "Ping-Wheel-" + ) + ) + @Suppress("SpellCheckingInspection") private var fallbackMods = TreeSet( listOf( @@ -257,6 +267,7 @@ actual class ApiProperties( "Reforgium-", "ResourceLoader-", "ResourcePackOrganizer", + "Ryoamiclights-", "ShoulderSurfing-", "ShulkerTooltip-", "SimpleDiscordRichPresence-", @@ -417,6 +428,7 @@ actual class ApiProperties( "rubidium-", "rubidium_extras-", "screenshot-to-clipboard-", + "servercountryflags-", "shutupexperimentalsettings-", "shutupmodelloader-", "signtools-", @@ -561,6 +573,13 @@ actual class ApiProperties( var clientsideMods = fallbackMods private set + /** + * String-list of mods to include if present, regardless whether a match was found through [clientsideMods]. + */ + @Suppress("MemberVisibilityCanBePrivate") + var modsWhitelist = fallbackModsWhitelist + private set + /** * Regex-list of clientside-only mods to exclude from server packs. */ @@ -575,6 +594,20 @@ actual class ApiProperties( } private set + /** + * Regex-list of mods to include if present, regardless whether a match was found throug [clientsideModsRegex]. + */ + var modsWhitelistRegex: TreeSet<String> = TreeSet() + get() { + field.clear() + for (mod in modsWhitelist) { + field.add("^$mod.*$") + } + return field + } + private set + + /** * Modloaders supported by ServerPackCreator. */ @@ -1867,6 +1900,7 @@ actual class ApiProperties( log.info("Fallback lists updated.") } else { setFallbackModsList() + setFallbackWhitelist() } if (saveProps) { //Store properties in the configured SPC home-directory @@ -1891,10 +1925,24 @@ actual class ApiProperties( pConfigurationFallbackModsList, clientsideMods.joinToString(",") ) + } + /** + * Set up our fallback list of clientside-only mods. + * + * @author Griefed + */ + private fun setFallbackWhitelist() { + // Regular list + modsWhitelist.addAll( + getListProperty( + pConfigurationFallbackModsWhiteList, + fallbackModsWhitelist.joinToString(",") + ) + ) internalProps.setProperty( - pConfigurationFallbackModsListRegex, - clientsideModsRegex.joinToString(",") + pConfigurationFallbackModsWhiteList, + fallbackModsWhitelist.joinToString(",") ) } @@ -2217,9 +2265,24 @@ actual class ApiProperties( */ fun clientSideMods() = if (exclusionFilter == ExclusionFilter.REGEX) { - clientsideModsRegex.toList() as ArrayList<String> + clientsideModsRegex.toList() } else { - clientsideMods.toList() as ArrayList<String> + clientsideMods.toList() + } + + /** + * Acquire the default fallback list of whitelisted mods. If + * `de.griefed.serverpackcreator.serverpack.autodiscovery.filter` is set to + * [ExclusionFilter.REGEX], a regex fallback list is returned. + * + * @return The fallback list of whitelisted mods. + * @author Griefed + */ + fun whitelistedMods() = + if (exclusionFilter == ExclusionFilter.REGEX) { + modsWhitelistRegex.toList() + } else { + modsWhitelist.toList() } /** @@ -2257,6 +2320,19 @@ actual class ApiProperties( log.info("The fallback-list for clientside only mods has been updated to: $clientsideMods") updated = true } + if (properties!!.getProperty(pConfigurationFallbackModsWhiteList) != null && + internalProps.getProperty(pConfigurationFallbackModsWhiteList) + != properties!!.getProperty(pConfigurationFallbackModsWhiteList) + ) { + internalProps.setProperty( + pConfigurationFallbackModsWhiteList, + properties!!.getProperty(pConfigurationFallbackModsWhiteList) + ) + modsWhitelist.clear() + modsWhitelist.addAll(internalProps.getProperty(pConfigurationFallbackModsWhiteList).split(",")) + log.info("The fallback-list for whitelisted mods has been updated to: $modsWhitelist") + updated = true + } } if (updated) { saveProperties(File(homeDirectory, serverPackCreatorProperties).absoluteFile) 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 3600ee1069ed9c382d881128120c3a9929979c2e..7d29ab6dd100b695e066687d7d12320d5312e4c6 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 @@ -63,6 +63,7 @@ actual class ConfigurationHandler( val fileConf = PackConfig(utilities, configFile) packConfig.setClientMods(fileConf.clientMods) packConfig.setInclusions(fileConf.inclusions) + packConfig.setModsWhitelist(fileConf.modsWhitelist) packConfig.modpackDir = fileConf.modpackDir packConfig.minecraftVersion = fileConf.minecraftVersion packConfig.modloader = fileConf.modloader @@ -94,8 +95,13 @@ actual class ConfigurationHandler( log.info("Checking configuration...") if (packConfig.clientMods.isEmpty()) { log.warn("No clientside-only mods specified. Using fallback list.") - packConfig.setClientMods(apiProperties.clientSideMods()) + packConfig.setClientMods(apiProperties.clientSideMods().toMutableList()) } + if (packConfig.modsWhitelist.isEmpty()) { + log.warn("No whitelist mods specified. Using fallback list.") + packConfig.setModsWhitelist(apiProperties.whitelistedMods().toMutableList()) + } + if (!checkIconAndProperties(packConfig.serverIconPath)) { configCheck.serverIconErrors.add(Api.configuration_log_error_servericon(packConfig.serverIconPath)) log.error("The specified server-icon does not exist: ${packConfig.serverIconPath}") 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 ba61beccbb7b1fd99c29b9bd480d0c4e0a96aaad..bede9a54809774ad0fd8f187bbe61e969f29aa61 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 @@ -70,6 +70,11 @@ private const val clientModsComment = "\n No need to include version specifics. Must be the filenames of the mods, not their project names on CurseForge/Modrinth!" + "\n Example: [AmbientSounds-,ClientTweaks-,PackMenu-,BetterAdvancement-,jeiintegration-]" +private const val whitelistComment = + "\n List of mods to include if present, regardless whether a match was found through the list of clientside-only mods." + + "\n No need to include version specifics. Must be the filenames of the mods, not their project names on CurseForge/Modrinth!" + + "\n Example: [Ping-Wheel-]" + private const val includeServerPropertiesComment = "\n Include a server.properties in your server pack. Must be true or false." + "\n If no server.properties is provided but setting set to true, a default one will be provided. Default value is true." @@ -118,6 +123,8 @@ private const val inclusionsKey = "inclusions" private const val clientModsKey = "clientMods" +private const val whitelistKey = "whitelist" + private const val includeServerPropertiesKey = "includeServerProperties" private const val includeServerIconKey = "includeServerIcon" @@ -187,6 +194,7 @@ actual open class PackConfig actual constructor() : Pack<File, JsonNode, PackCon * Construct a new configuration model with custom values. * * @param clientMods List of clientside mods to exclude from the server pack. + * @param whitelist List of mods to include if present, regardless whether a match was found through [clientMods] * @param copyDirs List of directories and/or files to include in the server pack. * @param modpackDir The path to the modpack. * @param minecraftVersion The Minecraft version the modpack uses. @@ -206,6 +214,7 @@ actual open class PackConfig actual constructor() : Pack<File, JsonNode, PackCon */ actual constructor( clientMods: List<String>, + whitelist: List<String>, copyDirs: List<InclusionSpecification>, modpackDir: String, minecraftVersion: String, @@ -284,7 +293,8 @@ actual open class PackConfig actual constructor() : Pack<File, JsonNode, PackCon } setInclusions(inclusionSpecs) - setClientMods(config.getOrElse(clientModsKey, listOf("")) as ArrayList<String>) + setClientMods(config.getOrElse(clientModsKey, listOf("")).toMutableList()) + setModsWhitelist(config.getOrElse(whitelistKey, listOf("")).toMutableList()) modpackDir = config.getOrElse(modpackDirKey, "") minecraftVersion = config.getOrElse(minecraftVersionKey, "") modloader = config.getOrElse(modLoaderKey, "") @@ -401,6 +411,9 @@ actual open class PackConfig actual constructor() : Pack<File, JsonNode, PackCon conf.setComment(clientModsKey, clientModsComment) conf.set<Any>(clientModsKey, clientMods) + conf.setComment(whitelistKey, whitelistComment) + conf.set<Any>(whitelistKey, modsWhitelist) + conf.setComment(includeServerPropertiesKey, includeServerPropertiesComment) conf.set<Any>(includeServerPropertiesKey, isServerPropertiesInclusionDesired) 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 1736008ad79c676bab3180863c54b943e33690a9..d71a5358b11950f908eedcdb4c54c8379accf296 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 @@ -199,6 +199,7 @@ actual class ServerPackHandler actual constructor( modpackDir: String, inclusions: ArrayList<InclusionSpecification>, clientMods: List<String>, + whitelist: List<String>, minecraftVersion: String, destination: String, modloader: String @@ -233,6 +234,7 @@ actual class ServerPackHandler actual constructor( destination, exclusions, clientMods, + whitelist, minecraftVersion, modloader ) @@ -265,6 +267,7 @@ actual class ServerPackHandler actual constructor( destination: String, exclusions: MutableList<Regex>, clientMods: List<String>, + whitelist: List<String>, minecraftVersion: String, modloader: String ): List<ServerPackFile> { @@ -308,7 +311,7 @@ actual class ServerPackHandler actual constructor( } catch (ignored: IOException) { } acquired = mutableListOf() - for (mod in getModsToInclude(clientDir, clientMods, minecraftVersion, modloader)) { + for (mod in getModsToInclude(clientDir, clientMods, whitelist, minecraftVersion, modloader)) { acquired.add(ServerPackFile(mod, File(serverDir, mod.name))) } processed = runFilters(acquired, inclusion, modpackDir) @@ -817,6 +820,7 @@ actual class ServerPackHandler actual constructor( override fun getModsToInclude( modsDir: String, userSpecifiedClientMods: List<String>, + userSpecifiedModsWhitelist: List<String>, minecraftVersion: String, modloader: String ): List<File> { @@ -857,7 +861,7 @@ actual class ServerPackHandler actual constructor( } // Exclude user-specified mods from copying. - excludeUserSpecifiedMod(userSpecifiedClientMods, modsInModpack) + excludeUserSpecifiedMod(userSpecifiedClientMods, userSpecifiedModsWhitelist, modsInModpack) return ArrayList(modsInModpack) } @@ -975,11 +979,11 @@ actual class ServerPackHandler actual constructor( /** * @author Griefed */ - override fun excludeUserSpecifiedMod(userSpecifiedExclusions: List<String>, modsInModpack: TreeSet<File>) { + override fun excludeUserSpecifiedMod(userSpecifiedExclusions: List<String>, userSpecifiedModsWhitelist: List<String>, modsInModpack: TreeSet<File>) { if (userSpecifiedExclusions.isNotEmpty()) { log.info("Performing ${apiProperties.exclusionFilter}-type checks for user-specified clientside-only mod exclusion.") for (userSpecifiedExclusion in userSpecifiedExclusions) { - exclude(userSpecifiedExclusion, modsInModpack) + exclude(userSpecifiedExclusion, userSpecifiedModsWhitelist, modsInModpack) } } else { log.warn("User specified no clientside-only mods.") @@ -1022,22 +1026,23 @@ actual class ServerPackHandler actual constructor( /** * @author Griefed */ - override fun exclude(userSpecifiedExclusion: String, modsInModpack: TreeSet<File>) { - modsInModpack.removeIf { + override fun exclude(userSpecifiedExclusion: String, userSpecifiedModsWhitelist: List<String>, modsInModpack: TreeSet<File>) { + modsInModpack.removeIf { modToCheck -> val excluded: Boolean - val check = it.name + val modName = modToCheck.name excluded = when (apiProperties.exclusionFilter) { - ExclusionFilter.END -> check.endsWith(userSpecifiedExclusion) - ExclusionFilter.CONTAIN -> check.contains(userSpecifiedExclusion) - ExclusionFilter.REGEX -> check.matches(userSpecifiedExclusion.toRegex()) - ExclusionFilter.EITHER -> (check.startsWith(userSpecifiedExclusion) || check.endsWith( - userSpecifiedExclusion - ) || check.contains(userSpecifiedExclusion) || check.matches(userSpecifiedExclusion.toRegex())) - - ExclusionFilter.START -> check.startsWith(userSpecifiedExclusion) + ExclusionFilter.START -> modName.startsWith(userSpecifiedExclusion) && !userSpecifiedModsWhitelist.any { whitelistedMod -> modName.startsWith(whitelistedMod) } + ExclusionFilter.END -> modName.endsWith(userSpecifiedExclusion) && !userSpecifiedModsWhitelist.any { whitelistedMod -> modName.endsWith(whitelistedMod) } + ExclusionFilter.CONTAIN -> modName.contains(userSpecifiedExclusion) && !userSpecifiedModsWhitelist.any { whitelistedMod -> modName.contains(whitelistedMod) } + ExclusionFilter.REGEX -> modName.matches(userSpecifiedExclusion.toRegex()) && !userSpecifiedModsWhitelist.any { whitelistedMod -> modName.matches(whitelistedMod.toRegex()) } + ExclusionFilter.EITHER -> ( + (modName.startsWith(userSpecifiedExclusion) && !userSpecifiedModsWhitelist.any { whitelistedMod -> modName.startsWith(whitelistedMod) }) || + (modName.endsWith(userSpecifiedExclusion) && !userSpecifiedModsWhitelist.any { whitelistedMod -> modName.endsWith(whitelistedMod) }) || + (modName.contains(userSpecifiedExclusion) && !userSpecifiedModsWhitelist.any { whitelistedMod -> modName.contains(whitelistedMod) }) || + (modName.matches(userSpecifiedExclusion.toRegex()) && !userSpecifiedModsWhitelist.any { whitelistedMod -> modName.matches(whitelistedMod.toRegex()) })) } if (excluded) { - log.debug("Removed ${it.name} as per user-specified check: $userSpecifiedExclusion") + log.debug("Removed ${modToCheck.name} as per user-specified check: $userSpecifiedExclusion") } excluded } 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 1e874e0eb06512bb9804e81534d009e04b435ce0..57c37c242a2426a591b0b733968b7701ecd6c890 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 @@ -1,11 +1,18 @@ #!/usr/bin/env bash - +# NOTES AND GENERAL INFO +# # Start script generated by ServerPackCreator SPC_SERVERPACKCREATOR_VERSION_SPC. - +# +# The Linux scripts are intended to be run using bash (indicated by the `#!/usr/bin/env bash` at the top), +# i.e. by simply calling `./start.sh` or `bash start.sh`. +# Using any other method may work, but can also lead to unexpected behavior. +# Running the Linux scripts on MacOS has been done before, but is not tested by the developers of ServerPackCreator. +# Results may wary, no guarantees. +# # Depending on which modloader is set, different checks are run to ensure the server will start accordingly. # If the modloader checks and setup are passed, Minecraft and EULA checks are run. # If everything is in order, the server is started. - +# # Depending on the Minecraft version you will require a different Java version to run the server. # 1.16.5 and older requires Java 8 (Java 11 will run better and work with 99% of mods, give it a try) # Linux: diff --git a/serverpackcreator-api/src/jvmMain/resources/serverpackcreator.properties b/serverpackcreator-api/src/jvmMain/resources/serverpackcreator.properties index 47aa0b6fc3ea7d3b926d3ec9f80b7908ff8e2ac5..2678a76c94750e63318ed35cd877ef44e967794b 100644 --- a/serverpackcreator-api/src/jvmMain/resources/serverpackcreator.properties +++ b/serverpackcreator-api/src/jvmMain/resources/serverpackcreator.properties @@ -2,7 +2,8 @@ de.griefed.serverpackcreator.versioncheck.prerelease=false de.griefed.serverpackcreator.language=en_GB de.griefed.serverpackcreator.configuration.fallback.updateurl=https://raw.githubusercontent.com/Griefed/ServerPackCreator/main/serverpackcreator-api/src/jvmMain/resources/serverpackcreator.properties -de.griefed.serverpackcreator.configuration.fallbackmodslist=3dskinlayers-,Absolutely-Not-A-Zoom-Mod-,AdvancedChat-,AdvancedChatCore-,AdvancedChatHUD-,AdvancedCompas-,Ambience,AmbientEnvironment-,AmbientSounds_,AreYouBlind-,Armor Status HUD-,ArmorSoundTweak-,BH-Menu-,Batty's Coordinates PLUS Mod,BetterAdvancements-,BetterAnimationsCollection-,BetterModsButton-,BetterDarkMode-,BetterF3-,BetterFog-,BetterFoliage-,BetterPingDisplay-,BetterPlacement-,BetterTaskbar-,BetterThirdPerson,BetterTitleScreen-,Blur-,BorderlessWindow-,CTM-,ChunkAnimator-,ClientTweaks_,CompletionistsIndex-,Controller Support-,Controlling-,CraftPresence-,Create_Questing-,CullLessLeaves-Reforged-,CustomCursorMod-,CustomMainMenu-,DefaultOptions_,DefaultSettings-,DeleteWorldsToTrash-,DetailArmorBar-,Ding-,DistantHorizons-,DripSounds-,Durability101-,DurabilityNotifier-,DynamicSurroundings-,DynamicSurroundingsHuds-,EffectsLeft-,EiraMoticons_,EnchantmentDescriptions-,EnhancedVisuals_,EquipmentCompare-,FPS-Monitor-,FabricCustomCursorMod-,Fallingleaves-,FancySpawnEggs,FancyVideo-API-,FirstPersonMod,FogTweaker-,ForgeCustomCursorMod-,FpsReducer-,FpsReducer2-,FullscreenWindowed-,GameMenuModOption-,HealthOverlay-,HeldItemTooltips-,HorseStatsMod-,ImmediatelyFastReforged-,InventoryEssentials_,InventoryHud_[1.17.1].forge-,InventorySpam-,InventoryTweaks-,ItemBorders-,ItemPhysicLite_,ItemStitchingFix-,JBRA-Client-,JustEnoughCalculation-,JustEnoughEffects-,JustEnoughProfessions-,LeaveMyBarsAlone-,LLOverlayReloaded-,LOTRDRP-,LegendaryTooltips,LegendaryTooltips-,LightOverlay-,MoBends,MouseTweaks-,MyServerIsCompatible-,Neat ,Neat-,NekosEnchantedBooks-,NoAutoJump-,NoFog-,Notes-,NotifMod-,OldJavaWarning-,OptiFine,OptiFine_,OptiForge,OptiForge-,OverflowingBars-,PackMenu-,PackModeMenu-,PickUpNotifier-,Ping-,PingHUD-,PresenceFootsteps-,RPG-HUD-,ReAuth-,Reforgium-,ResourceLoader-,ResourcePackOrganizer,ShoulderSurfing-,ShulkerTooltip-,SimpleDiscordRichPresence-,SimpleWorldTimer-,SoundFilters-,SpawnerFix-,StylishEffects-,TextruesRubidiumOptions-,TRansliterationLib-,TipTheScales-,Tips-,Toast Control-,Toast-Control-,ToastControl-,TravelersTitles-,VoidFog-,VR-Combat_,WindowedFullscreen-,WorldNameRandomizer-,[1.12.2]DamageIndicatorsMod-,[1.12.2]bspkrscore-,antighost-,anviltooltipmod-,appleskin-,armorchroma-,armorpointspp-,auditory-,authme-,auto-reconnect-,autojoin-,autoreconnect-,axolotl-item-fix-,backtools-,bannerunlimited-,beenfo-1.19-,better-recipe-book-,betterbiomeblend-,bhmenu-,blur-,borderless-mining-,catalogue-,charmonium-,chat_heads-,cherishedworlds-,cirback-1.0-,classicbar-,clickadv-,clienttweaks-,combat_music-,connectedness-,controllable-,cullleaves-,cullparticles-,custom-crosshair-mod-,customdiscordrpc-,darkness-,dashloader-,defaultoptions-,desiredservers-,discordrpc-,drippyloadingscreen-,drippyloadingscreen_,durabilitytooltip-,dynamic-fps-,dynamic-music-,dynamiclights-,dynmus-,effective-,eggtab-,eguilib-,eiramoticons-,embeddium-,enchantment-lore-,entity-texture-features-,entityculling-,essential_,exhaustedstamina-,extremesoundmuffler-,fabricemotes-,fancymenu_,fancymenu_video_extension,flickerfix-,fm_audio_extension_,forgemod_VoxelMap-,freelook-,galacticraft-rpc-,gamestagesviewer-,gpumemleakfix-,grid-,helium-,hiddenrecipebook_,hiddenrecipebook-,infinitemusic-,inventoryprofiles,invtweaks-,itemzoom,itlt-,jeed-,jehc-,jeiintegration_,just-enough-harvestcraft-,justenoughbeacons-,justenoughdrags-,justzoom_,keymap-,keywizard-,lazydfu-,lib39-,light-overlay-,lightfallclient-,lightspeed-,loadmyresources_,lock_minecart_view-,lootbeams-,lwl-,magnesium_extras-,maptooltip-,massunbind,mcbindtype-,mcwifipnp-,medievalmusic-,memoryusagescreen-,mightyarchitect-,mindful-eating-,minetogether-,mobplusplus-,modcredits-,modernworldcreation_,modnametooltip-,modnametooltip_,moreoverlays-,mousewheelie-,movement-vision-,multihotbar-,music-duration-reducer-,musicdr-,neiRecipeHandlers-,ngrok-lan-expose-mod-,no_nv_flash-,nopotionshift_,notenoughanimations-,oculus-,ornaments-,overloadedarmorbar-,panorama-,paperdoll-,physics-mod-,phosphor-,preciseblockplacing-,radon-,realm-of-lost-souls-,rebind_narrator-,rebind-narrator-,rebindnarrator-,rebrand-,reforgium-,replanter-,rubidium-,rubidium_extras-,screenshot-to-clipboard-,shutupexperimentalsettings-,shutupmodelloader-,signtools-,simple-rpc-,simpleautorun-,smartcursor-,smoothboot-,smoothfocus-,sodium-fabric-,sounddeviceoptions-,soundreloader-,spoticraft-,^textrues_embeddium_options-.*$,tconplanner-,textrues_embeddium_options-,timestamps-,tooltipscroller-,torchoptimizer-,torohealth-,totaldarkness,toughnessbar-,whats-that-slot-forge-,wisla-,xlifeheartcolors-,yisthereautojump- +de.griefed.serverpackcreator.configuration.fallbackmodslist=3dskinlayers-,Absolutely-Not-A-Zoom-Mod-,AdvancedChat-,AdvancedChatCore-,AdvancedChatHUD-,AdvancedCompas-,Ambience,AmbientEnvironment-,AmbientSounds_,AreYouBlind-,Armor Status HUD-,ArmorSoundTweak-,BH-Menu-,Batty's Coordinates PLUS Mod,BetterAdvancements-,BetterAnimationsCollection-,BetterModsButton-,BetterDarkMode-,BetterF3-,BetterFog-,BetterFoliage-,BetterPingDisplay-,BetterPlacement-,BetterTaskbar-,BetterThirdPerson,BetterTitleScreen-,Blur-,BorderlessWindow-,CTM-,ChunkAnimator-,ClientTweaks_,CompletionistsIndex-,Controller Support-,Controlling-,CraftPresence-,Create_Questing-,CullLessLeaves-Reforged-,CustomCursorMod-,CustomMainMenu-,DefaultOptions_,DefaultSettings-,DeleteWorldsToTrash-,DetailArmorBar-,Ding-,DistantHorizons-,DripSounds-,Durability101-,DurabilityNotifier-,DynamicSurroundings-,DynamicSurroundingsHuds-,EffectsLeft-,EiraMoticons_,EnchantmentDescriptions-,EnhancedVisuals_,EquipmentCompare-,FPS-Monitor-,FabricCustomCursorMod-,Fallingleaves-,FancySpawnEggs,FancyVideo-API-,FirstPersonMod,FogTweaker-,ForgeCustomCursorMod-,FpsReducer-,FpsReducer2-,FullscreenWindowed-,GameMenuModOption-,HealthOverlay-,HeldItemTooltips-,HorseStatsMod-,ImmediatelyFastReforged-,InventoryEssentials_,InventoryHud_[1.17.1].forge-,InventorySpam-,InventoryTweaks-,ItemBorders-,ItemPhysicLite_,ItemStitchingFix-,JBRA-Client-,JustEnoughCalculation-,JustEnoughEffects-,JustEnoughProfessions-,LeaveMyBarsAlone-,LLOverlayReloaded-,LOTRDRP-,LegendaryTooltips,LegendaryTooltips-,LightOverlay-,MoBends,MouseTweaks-,MyServerIsCompatible-,Neat ,Neat-,NekosEnchantedBooks-,NoAutoJump-,NoFog-,Notes-,NotifMod-,OldJavaWarning-,OptiFine,OptiFine_,OptiForge,OptiForge-,OverflowingBars-,PackMenu-,PackModeMenu-,PickUpNotifier-,Ping-,PingHUD-,PresenceFootsteps-,RPG-HUD-,ReAuth-,Reforgium-,ResourceLoader-,ResourcePackOrganizer,Ryoamiclights-,ShoulderSurfing-,ShulkerTooltip-,SimpleDiscordRichPresence-,SimpleWorldTimer-,SoundFilters-,SpawnerFix-,StylishEffects-,TextruesRubidiumOptions-,TRansliterationLib-,TipTheScales-,Tips-,Toast Control-,Toast-Control-,ToastControl-,TravelersTitles-,VoidFog-,VR-Combat_,WindowedFullscreen-,WorldNameRandomizer-,[1.12.2]DamageIndicatorsMod-,[1.12.2]bspkrscore-,antighost-,anviltooltipmod-,appleskin-,armorchroma-,armorpointspp-,auditory-,authme-,auto-reconnect-,autojoin-,autoreconnect-,axolotl-item-fix-,backtools-,bannerunlimited-,beenfo-1.19-,better-recipe-book-,betterbiomeblend-,bhmenu-,blur-,borderless-mining-,catalogue-,charmonium-,chat_heads-,cherishedworlds-,cirback-1.0-,classicbar-,clickadv-,clienttweaks-,combat_music-,connectedness-,controllable-,cullleaves-,cullparticles-,custom-crosshair-mod-,customdiscordrpc-,darkness-,dashloader-,defaultoptions-,desiredservers-,discordrpc-,drippyloadingscreen-,drippyloadingscreen_,durabilitytooltip-,dynamic-fps-,dynamic-music-,dynamiclights-,dynmus-,effective-,eggtab-,eguilib-,eiramoticons-,embeddium-,enchantment-lore-,entity-texture-features-,entityculling-,essential_,exhaustedstamina-,extremesoundmuffler-,fabricemotes-,fancymenu_,fancymenu_video_extension,flickerfix-,fm_audio_extension_,forgemod_VoxelMap-,freelook-,galacticraft-rpc-,gamestagesviewer-,gpumemleakfix-,grid-,helium-,hiddenrecipebook_,hiddenrecipebook-,infinitemusic-,inventoryprofiles,invtweaks-,itemzoom,itlt-,jeed-,jehc-,jeiintegration_,just-enough-harvestcraft-,justenoughbeacons-,justenoughdrags-,justzoom_,keymap-,keywizard-,lazydfu-,lib39-,light-overlay-,lightfallclient-,lightspeed-,loadmyresources_,lock_minecart_view-,lootbeams-,lwl-,magnesium_extras-,maptooltip-,massunbind,mcbindtype-,mcwifipnp-,medievalmusic-,memoryusagescreen-,mightyarchitect-,mindful-eating-,minetogether-,mobplusplus-,modcredits-,modernworldcreation_,modnametooltip-,modnametooltip_,moreoverlays-,mousewheelie-,movement-vision-,multihotbar-,music-duration-reducer-,musicdr-,neiRecipeHandlers-,ngrok-lan-expose-mod-,no_nv_flash-,nopotionshift_,notenoughanimations-,oculus-,ornaments-,overloadedarmorbar-,panorama-,paperdoll-,physics-mod-,phosphor-,preciseblockplacing-,radon-,realm-of-lost-souls-,rebind_narrator-,rebind-narrator-,rebindnarrator-,rebrand-,reforgium-,replanter-,rubidium-,rubidium_extras-,screenshot-to-clipboard-,servercountryflags-,shutupexperimentalsettings-,shutupmodelloader-,signtools-,simple-rpc-,simpleautorun-,smartcursor-,smoothboot-,smoothfocus-,sodium-fabric-,sounddeviceoptions-,soundreloader-,spoticraft-,^textrues_embeddium_options-.*$,tconplanner-,textrues_embeddium_options-,timestamps-,tooltipscroller-,torchoptimizer-,torohealth-,totaldarkness,toughnessbar-,whats-that-slot-forge-,wisla-,xlifeheartcolors-,yisthereautojump- +de.griefed.serverpackcreator.configuration.modswhitelist=Ping-Wheel- de.griefed.serverpackcreator.configuration.hastebinserver=https://haste.zneix.eu/documents de.griefed.serverpackcreator.configuration.aikar=-Xms4G -Xmx4G -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 de.griefed.serverpackcreator.serverpack.autodiscovery.enabled=true diff --git a/serverpackcreator-api/src/jvmTest/kotlin/de/griefed/serverpackcreator/api/ConfigurationHandlerTest.kt b/serverpackcreator-api/src/jvmTest/kotlin/de/griefed/serverpackcreator/api/ConfigurationHandlerTest.kt index fcf4d24dd18df2872a4e4c3af332a1e865b984ce..529c03b644e135491f15175dc742d5d84e89b4b6 100644 --- a/serverpackcreator-api/src/jvmTest/kotlin/de/griefed/serverpackcreator/api/ConfigurationHandlerTest.kt +++ b/serverpackcreator-api/src/jvmTest/kotlin/de/griefed/serverpackcreator/api/ConfigurationHandlerTest.kt @@ -607,6 +607,9 @@ internal class ConfigurationHandlerTest { "TipTheScales", "WorldNameRandomizer" ) + val whitelist = arrayListOf( + "Ping-Wheel-" + ) val inclusions = ArrayList<InclusionSpecification>() inclusions.add(InclusionSpecification("config")) inclusions.add(InclusionSpecification("mods")) @@ -628,6 +631,7 @@ internal class ConfigurationHandlerTest { Assertions.assertNotNull( PackConfig( clientMods, + whitelist, inclusions, "src/jvmTest/resources/fabric_tests", javaPath, @@ -676,6 +680,9 @@ internal class ConfigurationHandlerTest { "TipTheScales", "WorldNameRandomizer" ) + val whitelist = arrayListOf( + "Ping-Wheel-" + ) val inclusions = ArrayList<InclusionSpecification>() inclusions.add(InclusionSpecification("config")) inclusions.add(InclusionSpecification("mods")) @@ -696,6 +703,7 @@ internal class ConfigurationHandlerTest { Assertions.assertNotNull( PackConfig( clientMods, + whitelist, inclusions, "src/jvmTest/resources/forge_tests", javaPath, diff --git a/serverpackcreator-app/build.gradle.kts b/serverpackcreator-app/build.gradle.kts index bd2942cb6720618b3e64e6e8dd00848131650945..9e973bba0f6c1994aef0934f4ec0ac1a5c3056dc 100644 --- a/serverpackcreator-app/build.gradle.kts +++ b/serverpackcreator-app/build.gradle.kts @@ -22,7 +22,6 @@ dependencies { api(project(":serverpackcreator-gui")) api(project(":serverpackcreator-web")) api(project(":serverpackcreator-updater")) - //api("de.griefed:versionchecker:1.1.9") testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.0") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.0") } diff --git a/serverpackcreator-app/jpackagerResources/ServerPackCreator.desktop b/serverpackcreator-app/jpackagerResources/ServerPackCreator.desktop index 3c1128cd26147893354ce23f836cd21b900aa3f0..360537334f74ecb8fa60f6c0f040582139daf184 100644 --- a/serverpackcreator-app/jpackagerResources/ServerPackCreator.desktop +++ b/serverpackcreator-app/jpackagerResources/ServerPackCreator.desktop @@ -1,7 +1,11 @@ [Desktop Entry] Name=ServerPackCreator Comment=Create server packs from Minecraft Forge, Fabric, Quilt or LegacyFabric modpacks. -Exec=ServerPackCreator -Icon=ServerPackCreator +GenericName[en_US]=Create server packs from Minecraft Forge, Fabric, Quilt or LegacyFabric modpacks. +GenericName[en_GB]=Create server packs from Minecraft Forge, Fabric, Quilt or LegacyFabric modpacks. +Exec=/opt/serverpackcreator/bin/ServerPackCreator +Icon=/opt/serverpackcreator/lib/ServerPackCreator.png +Terminal=false Type=Application Categories=Utility;FileTools;Java; +MimeType= \ No newline at end of file diff --git a/serverpackcreator-app/jpackagerResources/launcher.desktop b/serverpackcreator-app/jpackagerResources/launcher.desktop new file mode 100644 index 0000000000000000000000000000000000000000..360537334f74ecb8fa60f6c0f040582139daf184 --- /dev/null +++ b/serverpackcreator-app/jpackagerResources/launcher.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Name=ServerPackCreator +Comment=Create server packs from Minecraft Forge, Fabric, Quilt or LegacyFabric modpacks. +GenericName[en_US]=Create server packs from Minecraft Forge, Fabric, Quilt or LegacyFabric modpacks. +GenericName[en_GB]=Create server packs from Minecraft Forge, Fabric, Quilt or LegacyFabric modpacks. +Exec=/opt/serverpackcreator/bin/ServerPackCreator +Icon=/opt/serverpackcreator/lib/ServerPackCreator.png +Terminal=false +Type=Application +Categories=Utility;FileTools;Java; +MimeType= \ No newline at end of file diff --git a/serverpackcreator-gui/src/main/i18n/Gui_en_GB.properties b/serverpackcreator-gui/src/main/i18n/Gui_en_GB.properties index 575b90d45bd93ac96a53cb8365ef080ee412ded0..8e03bb0de5a4e45b4b8c0c5f7601db53c0c88cf4 100644 --- a/serverpackcreator-gui/src/main/i18n/Gui_en_GB.properties +++ b/serverpackcreator-gui/src/main/i18n/Gui_en_GB.properties @@ -22,7 +22,9 @@ createserverpack.gui.createserverpack.labelsuffix=Server Pack Suffix createserverpack.gui.createserverpack.labelsuffix.tip=Optional. Suffix to append to the name of the server pack to be generated. createserverpack.gui.createserverpack.textsuffix.error=Server suffix contains illegal characters. createserverpack.gui.createserverpack.labelclientmods=Mod-Exclusions -createserverpack.gui.createserverpack.labelclientmods.tip=Comma separated. Example: AmbientSounds-,BackTools-,BetterAdvancement-,BetterPing- +createserverpack.gui.createserverpack.labelclientmods.tip=Mods to exclude from the server pack. Comma separated. Example: AmbientSounds-,BackTools-,BetterAdvancement-,BetterPing- +createserverpack.gui.createserverpack.labelwhitelistmods=Whitelisted Mods +createserverpack.gui.createserverpack.labelwhitelistmods.tip=Mods to include in the server pack, regardless of whether a match was found in the clientside-mods list. Comma separated. Example: Ping-Wheel. createserverpack.gui.createserverpack.textclientmods.error=Must not end with ',', spaces or contain illegal characters. createserverpack.gui.createserverpack.labelcopydirs=Server-files createserverpack.gui.createserverpack.labelcopydirs.tip=Comma separated. Example: mods, config, options.txt or explicit source/file;destination/file-combinations @@ -98,6 +100,13 @@ createserverpack.gui.buttonclientmods.revert.tip=Revert to last loaded configura createserverpack.gui.buttonclientmods.reset.tip=Reset to default createserverpack.gui.buttonclientmods.reset.merge.title=Custom values found! createserverpack.gui.buttonclientmods.reset.merge.message=Your clientside-mods contains entries not present in the default list.\nMerge yours with the default to keep your custom values?\nCaution! The resulting list may contain mods which should be present in the server!\nMerge only if you know what you are doing! +createserverpack.gui.buttonwhitelistmods=Open the file explorer to select the clientside-only mods in your modpack. +createserverpack.gui.buttonwhitelistmods.title=Select whitelisted mods in modpack. +createserverpack.gui.buttonwhitelistmods.filter=Minecraft Mod-Jar +createserverpack.gui.buttonwhitelistmods.revert.tip=Revert to last loaded configuration value +createserverpack.gui.buttonwhitelistmods.reset.tip=Reset to default +createserverpack.gui.buttonwhitelistmods.reset.merge.title=Custom values found! +createserverpack.gui.buttonwhitelistmods.reset.merge.message=Your whitelist contains entries not present in the default list.\nMerge yours with the default to keep your custom values?\nCaution! The resulting list may contain mods which should be present in the server!\nMerge only if you know what you are doing! createserverpack.gui.buttoncopydirs.revert.tip=Revert to last loaded configuration value createserverpack.gui.buttoncopydirs.reset.tip=Reset to default createserverpack.gui.buttoncopydirs=Open the file explorer to select the directories to include in the server pack. 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 b4041f46762ff6144a988d8074822f8d29860ff8..669f74472a761159fffc2b0808b04370878982c1 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 @@ -135,9 +135,10 @@ class ConfigEditor( private val prepareServerSetting = ActionCheckBox(Gui.createserverpack_gui_createserverpack_checkboxserver.toString(),validationActionListener) private val advSetExclusionsSetting = ScrollTextArea(apiWrapper.apiProperties.clientSideMods().joinToString(","),Gui.createserverpack_gui_createserverpack_labelclientmods.toString(),validationChangeListener, guiProps) + private val advSetWhitelistSetting = ScrollTextArea(apiWrapper.apiProperties.whitelistedMods().joinToString(","),Gui.createserverpack_gui_createserverpack_labelwhitelistmods.toString(),validationChangeListener, guiProps) private val advSetJavaArgsSetting = ScrollTextArea("-Xmx4G -Xms4G",Gui.createserverpack_gui_createserverpack_javaargs.toString(),validationChangeListener, guiProps) private val advSetScriptKVPairsSetting = ScriptKVPairs(guiProps, this) - private val advSetPanel = AdvancedSettingsPanel(this, advSetExclusionsSetting, advSetJavaArgsSetting, advSetScriptKVPairsSetting, guiProps, apiWrapper.apiProperties) + private val advSetPanel = AdvancedSettingsPanel(this, advSetExclusionsSetting, advSetWhitelistSetting, advSetJavaArgsSetting, advSetScriptKVPairsSetting, guiProps, apiWrapper.apiProperties) private val advSetCollapsible = CollapsiblePanel(Gui.createserverpack_gui_advanced.toString(), advSetPanel) private val pluginPanels = apiWrapper.apiPlugins!!.getConfigPanels(this).toMutableList() @@ -202,89 +203,100 @@ class ConfigEditor( updateMinecraftValues() // "cell column row width height" + var column = 0 // Modpack directory - panel.add(modpackIcon, "cell 0 0,grow") - panel.add(modpackLabel, "cell 1 0,grow") - panel.add(modpackSetting, "cell 2 0,grow") - panel.add(modpackChooser, "cell 3 0, h 30!,w 30!") - panel.add(modpackCheck, "cell 4 0") + panel.add(modpackIcon, "cell 0 $column,grow") + panel.add(modpackLabel, "cell 1 $column,grow") + panel.add(modpackSetting, "cell 2 $column,grow") + panel.add(modpackChooser, "cell 3 $column, h 30!,w 30!") + panel.add(modpackCheck, "cell 4 $column") // Server Properties - panel.add(propertiesIcon, "cell 0 1,grow") - panel.add(propertiesLabel) - panel.add(propertiesSetting, "cell 2 1, split 3,grow, w 50:50:") - panel.add(propertiesQuickSelectLabel, "cell 2 1") - panel.add(propertiesQuickSelect, "cell 2 1,w 200!") - panel.add(propertiesChooser, "cell 3 1") - panel.add(propertiesOpen, "cell 4 1") + column++ //1 + panel.add(propertiesIcon, "cell 0 $column,grow") + panel.add(propertiesLabel, "cell 1 $column,grow") + panel.add(propertiesSetting, "cell 2 $column, split 3,grow, w 50:50:") + panel.add(propertiesQuickSelectLabel, "cell 2 $column") + panel.add(propertiesQuickSelect, "cell 2 $column,w 200!") + panel.add(propertiesChooser, "cell 3 $column") + panel.add(propertiesOpen, "cell 4 $column") // Server Icon - panel.add(iconIcon, "cell 0 2,grow") - panel.add(iconLabel, "cell 1 2,grow") - panel.add(iconSetting, "cell 2 2, split 2,grow, w 50:50:") - panel.add(iconQuickSelectLabel, "cell 2 2") - panel.add(iconQuickSelect, "cell 2 2,w 200!") - panel.add(iconChooser, "cell 3 2") - panel.add(iconPreview, "cell 4 2") + column++ //2 + panel.add(iconIcon, "cell 0 $column,grow") + panel.add(iconLabel, "cell 1 $column,grow") + panel.add(iconSetting, "cell 2 $column, split 2,grow, w 50:50:") + panel.add(iconQuickSelectLabel, "cell 2 $column") + panel.add(iconQuickSelect, "cell 2 $column,w 200!") + panel.add(iconChooser, "cell 3 $column") + panel.add(iconPreview, "cell 4 $column") // Server Files - panel.add(inclusionsIcon, "cell 0 3 1 3") - panel.add(inclusionsLabel, "cell 1 3 1 3,grow") - panel.add(inclusionsSetting, "cell 2 3 3 3, grow, w 10:500:, h 150:225:300") + column++ //3 + panel.add(inclusionsIcon, "cell 0 $column 1 3") + panel.add(inclusionsLabel, "cell 1 $column 1 3,grow") + panel.add(inclusionsSetting, "cell 2 $column 3 3, grow, w 10:500:, h 150:225:300") // Server Pack Suffix - panel.add(suffixIcon, "cell 0 6,grow") - panel.add(suffixLabel, "cell 1 6,grow") - panel.add(suffixSetting, "cell 2 6 3 1,grow") + column += 3 //6 + panel.add(suffixIcon, "cell 0 $column,grow") + panel.add(suffixLabel, "cell 1 $column,grow") + panel.add(suffixSetting, "cell 2 $column 3 1,grow") // Minecraft Version - panel.add(mcVersionIcon, "cell 0 7,grow") - panel.add(mcVersionLabel, "cell 1 7,grow") - panel.add(mcVersionSetting, "cell 2 7,w 200!") + column++ //7 + panel.add(mcVersionIcon, "cell 0 $column,grow") + panel.add(mcVersionLabel, "cell 1 $column,grow") + panel.add(mcVersionSetting, "cell 2 $column,w 200!") // Java Version Of Minecraft Version - panel.add(javaVersionIcon, "cell 2 7, w 40!, gapleft 40") - panel.add(javaVersionLabel, "cell 2 7") - panel.add(javaVersionInfo, "cell 2 7, w 40!") + panel.add(javaVersionIcon, "cell 2 $column, w 40!, gapleft 40") + panel.add(javaVersionLabel, "cell 2 $column") + panel.add(javaVersionInfo, "cell 2 $column, w 40!") // Modloader - panel.add(modloaderIcon, "cell 0 8,grow") - panel.add(modloaderLabel, "cell 1 8,grow") - panel.add(modloaderSetting, "cell 2 8,w 200!") + column++ //8 + panel.add(modloaderIcon, "cell 0 $column,grow") + panel.add(modloaderLabel, "cell 1 $column,grow") + panel.add(modloaderSetting, "cell 2 $column,w 200!") // Include Server Icon - panel.add(includeIconIcon, "cell 2 8, w 40!, gapleft 40,grow") - panel.add(includeIconSetting, "cell 2 8, w 200!") + panel.add(includeIconIcon, "cell 2 $column, w 40!, gapleft 40,grow") + panel.add(includeIconSetting, "cell 2 $column, w 200!") // Create ZIP Archive - panel.add(zipIcon, "cell 2 8, w 40!,grow") - panel.add(zipSetting, "cell 2 8, w 200!") + panel.add(zipIcon, "cell 2 $column, w 40!,grow") + panel.add(zipSetting, "cell 2 $column, w 200!") // Modloader Version - panel.add(modloaderVersionIcon, "cell 0 9,grow") - panel.add(modloaderVersionLabel, "cell 1 9,grow") - panel.add(modloaderVersionSetting, "cell 2 9,w 200!") + column++ //9 + panel.add(modloaderVersionIcon, "cell 0 $column,grow") + panel.add(modloaderVersionLabel, "cell 1 $column,grow") + panel.add(modloaderVersionSetting, "cell 2 $column,w 200!") // Include Server Properties - panel.add(includePropertiesIcon, "cell 2 9, w 40!, gapleft 40,grow") - panel.add(includePropertiesSetting, "cell 2 9, w 200!") + panel.add(includePropertiesIcon, "cell 2 $column, w 40!, gapleft 40,grow") + panel.add(includePropertiesSetting, "cell 2 $column, w 200!") // Install Local Server - panel.add(prepareServerIcon, "cell 2 9, w 40!,grow") - panel.add(prepareServerSetting, "cell 2 9, w 200!") + panel.add(prepareServerIcon, "cell 2 $column, w 40!,grow") + panel.add(prepareServerSetting, "cell 2 $column, w 200!") // Advanced Settings - panel.add(advSetCollapsible, "cell 0 10 5,grow") + column++ //10 + panel.add(advSetCollapsible, "cell 0 $column 5,grow") // Plugins + column++ //11 if (pluginPanels.isNotEmpty()) { - panel.add(pluginPanel, "cell 0 11 5,grow") + panel.add(pluginPanel, "cell 0 $column 5,grow") } validateInputFields() lastConfig = getCurrentConfiguration() componentResizer.registerComponent(advSetExclusionsSetting, "cell 2 0 1 3,grow,w 10:500:,h %s!") - componentResizer.registerComponent(advSetJavaArgsSetting, "cell 2 3 1 3,grow,w 10:500:,h %s!") - componentResizer.registerComponent(advSetScriptKVPairsSetting.scrollPanel, "cell 2 6 1 3,grow,w 10:500:,h %s!") + componentResizer.registerComponent(advSetWhitelistSetting, "cell 2 3 1 3,grow,w 10:500:,h %s!") + componentResizer.registerComponent(advSetJavaArgsSetting, "cell 2 6 1 3,grow,w 10:500:,h %s!") + componentResizer.registerComponent(advSetScriptKVPairsSetting.scrollPanel, "cell 2 9 1 3,grow,w 10:500:,h %s!") } /** @@ -342,6 +354,14 @@ class ConfigEditor( validateInputFields() } + /** + * @author Griefed + */ + override fun setWhitelist(entries: MutableList<String>) { + advSetWhitelistSetting.text = apiWrapper.utilities!!.stringUtilities.buildString(entries) + validateInputFields() + } + /** * @author Griefed */ @@ -465,6 +485,13 @@ class ConfigEditor( return advSetExclusionsSetting.text.replace(", ", ",") } + /** + * @author Griefed + */ + override fun getWhitelist(): String { + return advSetWhitelistSetting.text.replace(", ", ",") + } + /** * @author Griefed */ @@ -476,6 +503,17 @@ class ConfigEditor( ) } + /** + * @author Griefed + */ + override fun getWhitelistList(): MutableList<String> { + return apiWrapper.utilities!!.listUtilities.cleanList( + getWhitelist().split(",") + .dropLastWhile { it.isEmpty() } + .toMutableList() + ) + } + /** * @author Griefed */ @@ -489,6 +527,7 @@ class ConfigEditor( override fun getCurrentConfiguration(): PackConfig { return PackConfig( getClientSideModsList(), + getWhitelistList(), getInclusions(), getModpackDirectory(), getMinecraftVersion(), @@ -740,6 +779,7 @@ class ConfigEditor( when { currentConfig.clientMods != lastConfig!!.clientMods + || currentConfig.modsWhitelist != lastConfig!!.modsWhitelist || currentConfig.inclusions != lastConfig!!.inclusions || currentConfig.javaArgs != lastConfig!!.javaArgs || currentConfig.minecraftVersion != lastConfig!!.minecraftVersion @@ -775,8 +815,14 @@ class ConfigEditor( try { setModpackDirectory(packConfig.modpackDir) if (packConfig.clientMods.isEmpty()) { - setClientSideMods(apiWrapper.apiProperties.clientSideMods()) - log.debug("Set clientMods with fallback list.") + setClientSideMods(apiWrapper.apiProperties.clientSideMods().toMutableList()) + log.debug("Set clientMods to fallback list.") + } else { + setClientSideMods(packConfig.clientMods) + } + if (packConfig.modsWhitelist.isEmpty()) { + setWhitelist(apiWrapper.apiProperties.whitelistedMods().toMutableList()) + log.debug("Set whitelist to fallback list.") } else { setClientSideMods(packConfig.clientMods) } @@ -986,6 +1032,15 @@ class ConfigEditor( return advSetPanel.validateExclusions() } + /** + * Validate the input field for client mods. + * + * @author Griefed + */ + fun validateWhitelist(): List<String> { + return advSetPanel.validateWhitelist() + } + /** * Validate the input field for copy directories. * diff --git a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/configs/components/ConfigCheckTimer.kt b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/configs/components/ConfigCheckTimer.kt index 52dde08fa8d563f03ed0449baa773b67e04749a5..851a90a8b3e18daaf8ca37291538d66e9a3cf37f 100644 --- a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/configs/components/ConfigCheckTimer.kt +++ b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/configs/components/ConfigCheckTimer.kt @@ -52,6 +52,9 @@ class ConfigCheckTimer(delay: Int, guiProps: GuiProps, tabbedConfigsTab: TabbedC launch { errors.addAll(editor.validateExclusions()) } + launch { + errors.addAll(editor.validateWhitelist()) + } launch { errors.addAll(editor.validateInclusions()) } diff --git a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/configs/components/advanced/AdvancedSettingsPanel.kt b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/configs/components/advanced/AdvancedSettingsPanel.kt index a3a542ed8ef8ed7e7939f4885b5b18e61b874f5c..86f76bbfc91efdc2dff74b53009428cf3ace5b50 100644 --- a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/configs/components/advanced/AdvancedSettingsPanel.kt +++ b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/configs/components/advanced/AdvancedSettingsPanel.kt @@ -46,6 +46,7 @@ import javax.swing.JPanel class AdvancedSettingsPanel( private val configEditor: ConfigEditor, exclusions: ScrollTextArea, + whitelisted: ScrollTextArea, javaArgs: ScrollTextArea, scriptKVPairs: ScriptKVPairs, private val guiProps: GuiProps, @@ -63,6 +64,12 @@ class AdvancedSettingsPanel( private val clientModsChooser = BalloonTipButton(null, guiProps.folderIcon, Gui.createserverpack_gui_browser.toString(), guiProps) { selectClientMods() } private val clientModsReset = BalloonTipButton(null, guiProps.resetIcon, Gui.createserverpack_gui_buttonclientmods_reset_tip.toString(), guiProps) { resetClientMods() } + private val whitelistModsIcon = StatusIcon(guiProps,Gui.createserverpack_gui_createserverpack_labelwhitelistmods_tip.toString()) + private val whitelistModsLabel = ElementLabel(Gui.createserverpack_gui_createserverpack_labelwhitelistmods.toString()) + private val whitelistModsRevert = BalloonTipButton(null, guiProps.revertIcon, Gui.createserverpack_gui_buttonwhitelistmods_revert_tip.toString(), guiProps) { revertWhitelist() } + private val whitelistModsChooser = BalloonTipButton(null, guiProps.folderIcon, Gui.createserverpack_gui_browser.toString(), guiProps) { selectWhitelist() } + private val whitelistModsReset = BalloonTipButton(null, guiProps.resetIcon, Gui.createserverpack_gui_buttonwhitelistmods_reset_tip.toString(), guiProps) { resetWhitelist() } + private val javaArgsIcon = StatusIcon(guiProps,Gui.createserverpack_gui_createserverpack_javaargs_tip.toString()) private val javaArgsLabel = ElementLabel(Gui.createserverpack_gui_createserverpack_javaargs.toString()) private val javaArgsAikarsFlagsButton = AikarsFlagsButton(configEditor, guiProps) @@ -73,26 +80,38 @@ class AdvancedSettingsPanel( private val advScriptSettingsReset = BalloonTipButton(null, guiProps.resetIcon, Gui.createserverpack_gui_reset.toString(), guiProps) { resetScriptKVPairs() } init { + var column = 0 // Mod Exclusions - add(clientModsIcon, "cell 0 0 1 3") - add(clientModsLabel, "cell 1 0 1 3") - add(exclusions, "cell 2 0 1 3,grow,w 10:500:,h 150!") - add(clientModsRevert, "cell 3 0 2 1, h 30!, aligny center, alignx center,growx") - add(clientModsChooser, "cell 3 1 2 1, h 30!, aligny center, alignx center,growx") - add(clientModsReset, "cell 3 2 2 1, h 30!, aligny top, alignx center,growx") + add(clientModsIcon, "cell 0 $column 1 3") + add(clientModsLabel, "cell 1 $column 1 3") + add(exclusions, "cell 2 $column 1 3,grow,w 10:500:,h 150!") + add(clientModsRevert, "cell 3 $column 2 1, h 30!, aligny center, alignx center,growx") + add(clientModsChooser, "cell 3 ${column + 1} 2 1, h 30!, aligny center, alignx center,growx") + add(clientModsReset, "cell 3 ${column + 2} 2 1, h 30!, aligny top, alignx center,growx") + + // Mod Whitelist + column += 3 + add(whitelistModsIcon, "cell 0 $column 1 3") + add(whitelistModsLabel, "cell 1 $column 1 3") + add(whitelisted, "cell 2 $column 1 3,grow,w 10:500:,h 150!") + add(whitelistModsRevert, "cell 3 $column 2 1, h 30!, aligny center, alignx center,growx") + add(whitelistModsChooser, "cell 3 ${column + 1} 2 1, h 30!, aligny center, alignx center,growx") + add(whitelistModsReset, "cell 3 ${column + 2} 2 1, h 30!, aligny top, alignx center,growx") // Java Arguments - add(javaArgsIcon, "cell 0 3 1 3") - add(javaArgsLabel, "cell 1 3 1 3") - add(javaArgs, "cell 2 3 1 3,grow,w 10:500:,h 100!") - add(javaArgsAikarsFlagsButton, "cell 3 3 2 3,growy") + column += 3 + add(javaArgsIcon, "cell 0 $column 1 3") + add(javaArgsLabel, "cell 1 $column 1 3") + add(javaArgs, "cell 2 $column 1 3,grow,w 10:500:,h 100!") + add(javaArgsAikarsFlagsButton, "cell 3 $column 2 3,growy") // Script Key-Value Pairs - add(advScriptSettingsIcon, "cell 0 6 1 3") - add(advScriptSettingsLabel, "cell 1 6 1 3") - add(scriptKVPairs.scrollPanel, "cell 2 6 1 3,grow,w 10:500:,h 200!") - add(advScriptSettingsRevert, "cell 3 6 2 1, h 30!, aligny center, alignx center,growx") - add(advScriptSettingsReset, "cell 3 7 2 1, h 30!, aligny top, alignx center,growx") + column += 3 + add(advScriptSettingsIcon, "cell 0 $column 1 3") + add(advScriptSettingsLabel, "cell 1 $column 1 3") + add(scriptKVPairs.scrollPanel, "cell 2 $column 1 3,grow,w 10:500:,h 200!") + add(advScriptSettingsRevert, "cell 3 $column 2 1, h 30!, aligny center, alignx center,growx") + add(advScriptSettingsReset, "cell 3 ${column + 1} 2 1, h 30!, aligny top, alignx center,growx") isVisible = false } @@ -110,6 +129,20 @@ class AdvancedSettingsPanel( } /** + * Reverts the list of whitelisted mods to the value of the last loaded configuration, if one + * is available. + * + * @author Griefed + */ + private fun revertWhitelist() { + if (configEditor.lastConfig != null) { + configEditor.setWhitelist(configEditor.lastConfig!!.modsWhitelist) + configEditor.validateInputFields() + } + } + + /** + * Let the user choose the mods to exclude by browsing the filesystem and selecting the mod-files. * @author Griefed */ private fun selectClientMods() { @@ -132,6 +165,30 @@ class AdvancedSettingsPanel( } /** + * Let the user choose the mods to whitelist by browsing the filesystem and selecting the mod-files. + * @author Griefed + */ + private fun selectWhitelist() { + val whitelistChooser = if (File(configEditor.getModpackDirectory(), "mods").isDirectory) { + WhitelistChooser(File(configEditor.getModpackDirectory(), "mods"), guiProps.defaultFileChooserDimension) + } else { + WhitelistChooser(guiProps.defaultFileChooserDimension) + } + + if (whitelistChooser.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION) { + val whitelist: Array<File> = whitelistChooser.selectedFiles + val whitelistFilenames: TreeSet<String> = TreeSet() + whitelistFilenames.addAll(configEditor.getWhitelistList()) + for (mod in whitelist) { + whitelistFilenames.add(mod.name) + } + configEditor.setWhitelist(whitelistFilenames.toMutableList()) + log.debug("Selected mods: $whitelistFilenames") + } + } + + /** + * Reset the clientside-mods list to the default value from the ServerPackCreator configuration. * @author Griefed */ private fun resetClientMods() { @@ -153,10 +210,40 @@ class AdvancedSettingsPanel( configEditor.setClientSideMods(set.toMutableList()) } - 1 -> configEditor.setClientSideMods(default) + 1 -> configEditor.setClientSideMods(default.toMutableList()) } } else { - configEditor.setClientSideMods(default) + configEditor.setClientSideMods(default.toMutableList()) + } + } + + /** + * Reset the whitelist to the default value from the ServerPackCreator configuration. + * @author Griefed + */ + private fun resetWhitelist() { + val current = configEditor.getWhitelistList() + val default = apiProperties.whitelistedMods() + if (!default.any { mod -> !default.contains(mod) }) { + when (JOptionPane.showConfirmDialog( + this, + Gui.createserverpack_gui_buttonwhitelistmods_reset_merge_message.toString(), + Gui.createserverpack_gui_buttonwhitelistmods_reset_merge_title.toString(), + JOptionPane.YES_NO_OPTION, + JOptionPane.WARNING_MESSAGE, + guiProps.warningIcon + )) { + 0 -> { + val set = TreeSet<String>() + set.addAll(current) + set.addAll(default) + configEditor.setWhitelist(set.toMutableList()) + } + + 1 -> configEditor.setWhitelist(default.toMutableList()) + } + } else { + configEditor.setWhitelist(default.toMutableList()) } } @@ -194,4 +281,23 @@ class AdvancedSettingsPanel( } return errors } + + /** + * Validate the input field for whitelisted mods. + * + * @author Griefed + */ + fun validateWhitelist(): List<String> { + val errors: MutableList<String> = ArrayList(10) + if (!configEditor.getWhitelist().matches(guiProps.whitespace)) { + whitelistModsIcon.info() + } else { + errors.add(Gui.configuration_log_error_formatting.toString()) + whitelistModsIcon.error("<html>${errors.joinToString("<br>")}</html>") + } + for (error in errors) { + log.error(error) + } + return errors + } } \ No newline at end of file diff --git a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/configs/components/advanced/WhitelistChooser.kt b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/configs/components/advanced/WhitelistChooser.kt new file mode 100644 index 0000000000000000000000000000000000000000..3a45611030a53cdca215f5a3495865c3e31285d6 --- /dev/null +++ b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/configs/components/advanced/WhitelistChooser.kt @@ -0,0 +1,48 @@ +/* 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.gui.window.configs.components.advanced + +import Gui +import de.griefed.serverpackcreator.gui.components.BaseFileChooser +import java.awt.Dimension +import java.io.File +import javax.swing.filechooser.FileNameExtensionFilter + +/** + * File-chooser to select mod-JARs to add to the clientside-mods list of a server pack config. + * + * @author Griefed + */ +class WhitelistChooser(current: File?, dimension: Dimension) : BaseFileChooser() { + constructor(dimension: Dimension) : this(null, dimension) + + init { + currentDirectory = current + isFileHidingEnabled = false + dialogTitle = Gui.createserverpack_gui_buttonwhitelistmods_title.toString() + fileSelectionMode = FILES_ONLY + fileFilter = FileNameExtensionFilter( + Gui.createserverpack_gui_buttonwhitelistmods_filter.toString(), "jar" + ) + isAcceptAllFileFilterUsed = false + isMultiSelectionEnabled = true + preferredSize = dimension + } +} \ No newline at end of file diff --git a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/configs/components/inclusions/InclusionsEditor.kt b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/configs/components/inclusions/InclusionsEditor.kt index 846afd9de1ac162c9772e9e15e980ffb32774437..caf1e92325fc12918ad12acaa21ec4ec99ea646c 100644 --- a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/configs/components/inclusions/InclusionsEditor.kt +++ b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/configs/components/inclusions/InclusionsEditor.kt @@ -276,6 +276,7 @@ class InclusionsEditor( apiWrapper.serverPackHandler!!.getServerPackDestination(configEditor.getCurrentConfiguration()), mutableListOf(), configEditor.getClientSideModsList(), + configEditor.getWhitelistList(), configEditor.getMinecraftVersion(), configEditor.getModloader() ) diff --git a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/control/components/LarsonScanner.kt b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/control/components/LarsonScanner.kt index 121df0487157bca7d96c23f364582240e8fe3422..387cca440249c735232081388e8b045d0bbe02d5 100644 --- a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/control/components/LarsonScanner.kt +++ b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/control/components/LarsonScanner.kt @@ -1302,12 +1302,14 @@ class LarsonScanner : JPanel { * @author Griefed */ fun run() { - timer = Timer(40) { + val delay = 60 + timer = Timer(delay) { if (this.isRunning) { eye.updatePosition() eye.repaint() } } + timer.delay = delay timer.isRepeats = true timer.isCoalesce = true timer.start()