diff options
39 files changed, 1028 insertions, 758 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0cb85ac0..8242eef3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -49,7 +49,7 @@ jobs: run: ./gradlew clean test remapJar --no-daemon - uses: actions/upload-artifact@v3 with: - path: build/libs/*-dep.jar + path: build/libs/*.jar - name: Update discord notification if: ${{ env.WEBHOOK_URL && success() }} run: | diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000..de01458a --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,34 @@ +name: Pre-Publish + +on: + push: + tags: + - "*" + +jobs: + build: + env: + GIT_URL: ${{ github.server_url }}/${{ github.repository }}/tree/${{ github.sha }} + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: 17 + distribution: temurin + - name: Set up gradle cache + uses: gradle/gradle-build-action@v2 + - name: Build with Gradle + run: ./gradlew clean test includeBackupRepo remapJar --no-daemon + env: + NEU_RELEASE: true + - uses: actions/upload-artifact@v3 + with: + path: build/libs/*.jar + - run: ./.github/workflows/upload-release.sh + env: + GH_TOKEN: ${{ github.token }} diff --git a/.github/workflows/push-to-modrinth.yaml b/.github/workflows/push-to-modrinth.yaml new file mode 100644 index 00000000..930ca13c --- /dev/null +++ b/.github/workflows/push-to-modrinth.yaml @@ -0,0 +1,28 @@ +on: + release: + types: + - published + +jobs: + upload-to-modrinth: + runs-on: ubuntu-latest + steps: + - uses: dsaltares/fetch-gh-release-asset@master + with: + version: ${{ release.id }} + regex: true + file: "*.jar" + token: ${{ secrets.GITHUB_TOKEN }} + - run: | + printf %s "$CHANGELOG" > CHANGELOG.md + env: + CHANGELOG: ${{ release.body }} + - uses: Kir-Antipov/mc-publish@v3.3 + with: + modrinth-id: GGamhqbw + modrinth-token: ${{ secrets.MODRINTH_TOKEN }} + files: "*.jar" + loaders: forge + game-versions: 1.8.9 + version: ${{ release.tag_name }} + # TODO: version-type: release diff --git a/.github/workflows/send_webhook_update.sh b/.github/workflows/send_webhook_update.sh index 7a6f932d..6111b53d 100755 --- a/.github/workflows/send_webhook_update.sh +++ b/.github/workflows/send_webhook_update.sh @@ -35,8 +35,8 @@ case "$STATUS" in SUCCESS) color="$COLOR_SUCCESS" status_message="Build succeeded." - to_upload=$(echo build/libs/*-dep.jar) - upload_name=NotEnoughUpdates-beta-dep.jar + to_upload=$(echo build/libs/*.jar) + upload_name=NotEnoughUpdates-beta.jar ;; esac diff --git a/.github/workflows/upload-release.sh b/.github/workflows/upload-release.sh new file mode 100755 index 00000000..2cbca693 --- /dev/null +++ b/.github/workflows/upload-release.sh @@ -0,0 +1,43 @@ +# +# Copyright (C) 2024 NotEnoughUpdates contributors +# +# This file is part of NotEnoughUpdates. +# +# NotEnoughUpdates 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 3 of the License, or (at your option) any later version. +# +# NotEnoughUpdates 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 NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. +# + +last_tag="$(git log --pretty='%H %D'|grep -oE 'tag: [^ ]+'|sed -E 's/tag: ([^ ,]+),?/\1/'|head -2|tail -1)" +echo "Generating notes from $last_tag" +TARGET_NAME="build/libs/NotEnoughUpdates-$GITHUB_REF_NAME.jar" +mv build/libs/*.jar "$TARGET_NAME" + +read -r -d '' extra_notes <<EOF +Modrinth download: TBD + +Do **NOT** trust any mod just because they publish a checksum associated with it. These check sums are meant to verify only that two files are identical. They are not a certificate of origin, or a guarantee for the author of these files. + +sha256sum: \`$(sha256sum "$TARGET_NAME"|cut -f 1 -d ' '| tr -d '\n')\` +md5sum: \`$(md5sum "$TARGET_NAME"|cut -f 1 -d ' '| tr -d '\n')\` + +EOF + +preReleaseParam="" +if echo "$GITHUB_REF_NAME" | grep -E '.*\.0'>/dev/null; then + preReleaseParam="--prerelease" +fi + +gh release create -t "NotEnoughUpdates $GITHUB_REF_NAME" --verify-tag "$GITHUB_REF_NAME" --generate-notes \ + --draft --notes-start-tag "$last_tag" $preReleaseParam \ + --notes "$extra_notes" "$TARGET_NAME" + @@ -27,3 +27,6 @@ run infer-out/ ciwork/ .DS_STORE +*.asc +secrets/* + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f77d0334..0d8b8ab9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -49,110 +49,55 @@ For quicker hot swapping or if the above does not work, you can install [Single <details> <summary>Minimized, for your convenience</summary> -> **Release Types** -> -> Right now we can create Full Releases, Pre Releases and Hotfixes. -> -> - A Full Release is sent to all users, regardless of update stream. -> - A Pre Release is only sent to users who have opted into receiving beta updates. -> - A Hotfix is only sent to users who have *not* opted into receiving beta updates. -> - Therefore, when a bug is fixed in a hotfix update, it should *also* be fixed in a separate prerelease update. -> On the other hand, not all bugs fixed in a prerelease update need to be also dispatched in a hotfix. - -### Creating a new Full Release - -> Full Releases should be bug free, feature complete, and ideally checked by not only the community, but also by Moulberry himself, if he so desires. - -- Edit `NotEnoughUpdates.java` and change - -```java -public static final String VERSION = "2.2.0-REL"; /* Update the VERSION name */ -public static final int VERSION_ID = 20200; /* Set the VERSION_ID to match the version name like so: MAJOR * 10000 + MINOR * 100 + PATCH */ -public static final int PRE_VERSION_ID = 0; /* Reset the PRE_VERSION_ID back to 0 */ -public static final int HOTFIX_VERSION_ID = 0; /* Reset the HOTFIX_VERSION_ID back to 0 */ -``` +### Preparing a release -- Build a jar from this, either using the CI in GitHub actions, or using `gradle remapJar` directly. - - If building locally, make sure that all your changes are in version control so that the commit hash is set correctly (A non `dirty` jar) -- Create a GitHub release (marked as full release). This should also simultaneously create a tag on which to base future hotfixes. -- Edit the `update.json` in the repository and change - -```json5 -{ - "version": "2.1.0-REL", /* Update to match the VERSION name in java */ - "version_id": 20100, /* Update to match the VERSION_ID in java */ - "update_msg": "§7§m§l--------------------§6§l[§c§lNEU§6§l]§7§m§l--------------------\n\n§7A new version, v§6{version}§7, is now available!\n ", /* Update the version name. Remove old patch notes; Optionally add in a short new patch note. */ - "pre_version": "0.0", /* Reset to 0.0 */ - "pre_version_id": 0, /* Reset to 0 */ - "update_link": "https://github.com/NotEnoughUpdates/NotEnoughUpdates/releases/tag/<VERSIONNAME>", /* Change download link to the GitHub release */ - "update_direct": "https://github.com/NotEnoughUpdates/NotEnoughUpdates/releases/download/<VERSIONNAME>/NotEnoughUpdates-<VERSIONNAME>.jar", /* Change direct link to a direct download link */ -} -``` +To prepare a release, first merge all the PRs that you want, and then tag that resulting merge commit using `git tag <version>`. +Do *not* use a `vX.X.X` prefix, just raw-dog the `X.X.X` version. If you want this to be a pre-release set the patch version +to something `!= 0`. Note that we follow normal semver rules here, so `3.1.1 > 3.1.0`. -- Launch the game in an older version with this new repo locally to test the messages look first, then push to the central NEU repo (both `master` and `dangerous`) -- Create an announcement in discord [#neu-download](https://discord.com/channels/516977525906341928/693586404256645231). +GitHub actions will automatically build a JAR and generate a changelog and upload both to a draft release. Now you rally +the troups and get your fellow contributors to sign this JAR. -### Creating a pre-release +### Signing a release -> Pre-releases are intended to be mostly feature complete, mostly bug free releases that either don't have enough changes to justify a new Full Release, or have outstanding PRs that are probably merged soon. +The generated draft release should contain a sha256 hash sum. Copy that hash sum for later. -- Edit `NotEnoughUpdates.java` and change +Make sure you have [generated a key](#generating-a-key). -```java -public static final String VERSION = "2.2.0-REL"; /* The VERSION name should still be the same as the latest previously released FULL release */ -public static final int VERSION_ID = 20200; /* Same as VERSION name */ -public static final int PRE_VERSION_ID = 1; /* Increment the PRE_VERSION_ID */ -``` +Run `./gradlew signRelease`. Paste in the sha256 hash from earlier. It will generate a `.asc` signature for every +`secret/` you have. -- Build a jar from this, either using the CI in GitHub actions, or using `gradle remapJar` directly. - - If building locally, make sure that all your changes are in version control so that the commit hash is set correctly (A non `dirty` jar) -- Create a GitHub release (marked as pre-release) -- Edit the `update.json` in the repository and change - -```json5 -{ - "version": "2.1.0-REL", /* The VERSION name should still be the same as the latest previously released FULL release */ - "version_id": 20100, /* Same as VERSION name */ - "pre_update_msg": "§7§m§l--------------------§5§l[§c§lNEU§5§l]§7§m§l--------------------\n\n§7A new pre-release, v§52.0-PRE{pre_version}§7, is now available!\n ", /* Update the version name. Remove old patch notes; Optionally add in a short new patch note. */ - "pre_version": "0.0", /* Set to a new string (preferably increase the major version every time, except for hotfixes on the prerelease stream) */ - "pre_version_id": 0, /* Set to PRE_VERSION_ID from java */ - "pre_update_link": "https://github.com/NotEnoughUpdates/NotEnoughUpdates/releases/tag/<VERSIONNAME>", /* Change download link to the GitHub release */ - "pre_update_direct": "https://github.com/NotEnoughUpdates/NotEnoughUpdates/releases/download/<VERSIONNAME>/NotEnoughUpdates-<VERSIONNAME>.jar", /* Change direct link to a direct download link */ -} -``` +Copy those secrets into the draft release. -- Launch the game in an older version with this new repo locally to test the messages look first, then push to the central NEU repo (both `master` and `dangerous`, as some prerelease people sadly don't know how to change repo branches) -- Create an announcement in discord [#unofficial-prereleases](https://discord.com/channels/516977525906341928/837679819487313971). +### Publishing a release -### Creating a Hotfix +Once all relevant personnel have signed off on the release, the release can be published. It should be automatically +available to all people with an auto updater, and be automatically published on modrinth too. The release needs to be +manually uploaded to discord. -> Hotfixes spring off of a Full Release and intend to fix bugs and security flaws. They can, but ideally shouldn't, contain features from pre-releases and are intended as a drop in replacement of the current full release of NEU. These bug fixes should ideally also be released as a pre-release in tandem with the hotfix. +### Generating a key -- Edit `NotEnoughUpdates.java` and change +If you haven't generated a key yet, and you have been told to get one, this is how. -```java -public static final String VERSION = "2.2.0-REL"; /* The VERSION name should still be the same as the latest previously released FULL release */ -public static final int VERSION_ID = 20200; /* Same as VERSION name */ -public static final int PRE_VERSION_ID = 0; /* The PRE_VERSION_ID should still be 0 (as this is based off a full release) */ -public static final int HOTFIX_VERSION_ID = 1; /* Increment the HOTFIX_VERSION_ID */ -``` +For your first key generation, you will need to use openssl. -- Build a jar from this, either using the CI in GitHub actions, or using `gradle remapJar` directly. - - If building locally, make sure that all your changes are in version control so that the commit hash is set correctly (A non `dirty` jar) -- Create a GitHub release (marked as full release) -- Edit the previous FULL release on GitHub with a link to the new release. -- Edit the `update.json` in the repository and change - -```json5 -{ - "version": "2.1.0-REL", /* This version should still remain the same as the last full release */ - "version_id": 20100, /* Same as version */ - "update_msg": "§7§m§l--------------------§6§l[§c§lNEU§6§l]§7§m§l--------------------\n\n§7A new version, v§6{version}§7, is now available!\n ", /* Update the version name. Don't remove old patch notes; Optionally add in a short new patch note. Indicate that there is a hotfix present */ - "update_link": "https://github.com/NotEnoughUpdates/NotEnoughUpdates/releases/tag/<VERSIONNAME>", /* Change download link to the GitHub release */ - "update_direct": "https://github.com/NotEnoughUpdates/NotEnoughUpdates/releases/download/<VERSIONNAME>/NotEnoughUpdates-<VERSIONNAME>.jar", /* Change direct link to a direct download link */ -} +```bash +# Generate an RSA private key +openssl genpkey -out id_rsa.pem -algorithm RSA # This step can be skipped, if you want to re-use an existing *RSA* key. + +# Convert your RSA key to pkcs8, without a password protection +openssl pkcs8 -in id_rsa.pem -outform DER -out myname.der -topk8 -nocrypt + +# Generate a public key from your pkcs8 private key +openssl rsa -pubout -in id_rsa.pem -outform der -out myname.key ``` -- Launch the game in an older version with this new repo locally to test the messages look first, then push to the central NEU repo (both `master` and `dangerous`) -- Create an announcement in discord [#neu-download](https://discord.com/channels/516977525906341928/693586404256645231). +Now you have 3 files: + +- `id_rsa.pem` is your base private key. Store it safely somewhere else (maybe on a USB stick). Never share this one. +- `myname.der` is your secret. Put it in the `secrets/` folder in your NEU repo. Never share this one. +- `myname.key` is your public key. Put it in the `src/main/resources/trusted_team_members` folder. + +Make sure that the names of the `.der` and the `.key` file match. + </details> diff --git a/build.gradle.kts b/build.gradle.kts index 5ff7c7ce..087212ef 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -18,10 +18,12 @@ */ +import neubs.CustomSignTask import neubs.NEUBuildFlags import neubs.applyPublishingInformation import neubs.setVersionFromEnvironment import org.apache.commons.lang3.SystemUtils +import org.gradle.api.tasks.testing.logging.TestExceptionFormat import java.net.URL plugins { @@ -35,6 +37,7 @@ plugins { kotlin("jvm") version "1.8.21" id("io.gitlab.arturbosch.detekt") version "1.23.0" id("com.google.devtools.ksp") version "1.8.21-1.0.11" + id("net.kyori.blossom") version "2.1.0" } @@ -44,7 +47,7 @@ apply<NEUBuildFlags>() group = "io.github.moulberry" -setVersionFromEnvironment("2.1.1") +val baseVersion = setVersionFromEnvironment() // Minecraft configuration: loom { @@ -81,17 +84,18 @@ loom { // Dependencies: repositories { - mavenCentral() - mavenLocal() - maven("https://maven.notenoughupdates.org/releases") - maven("https://repo.spongepowered.org/maven/") - maven("https://pkgs.dev.azure.com/djtheredstoner/DevAuth/_packaging/public/maven/v1") - maven("https://jitpack.io") - maven("https://repo.polyfrost.cc/releases") + mavenCentral() + mavenLocal() + maven("https://maven.notenoughupdates.org/releases") + maven("https://repo.spongepowered.org/maven/") + maven("https://pkgs.dev.azure.com/djtheredstoner/DevAuth/_packaging/public/maven/v1") + maven("https://jitpack.io") + maven("https://repo.nea.moe/releases") + maven("https://repo.polyfrost.cc/releases") } val shadowImplementation: Configuration by configurations.creating { - configurations.implementation.get().extendsFrom(this) + configurations.implementation.get().extendsFrom(this) } val shadowOnly: Configuration by configurations.creating { @@ -99,138 +103,144 @@ val shadowOnly: Configuration by configurations.creating { } val shadowApi: Configuration by configurations.creating { - configurations.api.get().extendsFrom(this) + configurations.api.get().extendsFrom(this) } val devEnv: Configuration by configurations.creating { - configurations.runtimeClasspath.get().extendsFrom(this) - isCanBeResolved = false - isCanBeConsumed = false - isVisible = false + configurations.runtimeClasspath.get().extendsFrom(this) + isCanBeResolved = false + isCanBeConsumed = false + isVisible = false } val kotlinDependencies: Configuration by configurations.creating { - configurations.implementation.get().extendsFrom(this) + configurations.implementation.get().extendsFrom(this) } val mixinRTDependencies: Configuration by configurations.creating { - configurations.implementation.get().extendsFrom(this) + configurations.implementation.get().extendsFrom(this) } val oneconfigQuarantineSourceSet: SourceSet = sourceSets.create("oneconfig") { - java { - srcDir(layout.projectDirectory.dir("src/main/oneconfig")) - } + java { + srcDir(layout.projectDirectory.dir("src/main/oneconfig")) + } } configurations { - val main = getByName(sourceSets.main.get().compileClasspathConfigurationName) - "oneconfigImplementation" { - extendsFrom(main) - } + val main = getByName(sourceSets.main.get().compileClasspathConfigurationName) + "oneconfigImplementation" { + extendsFrom(main) + } } dependencies { - minecraft("com.mojang:minecraft:1.8.9") - mappings("de.oceanlabs.mcp:mcp_stable:22-1.8.9") - forge("net.minecraftforge:forge:1.8.9-11.15.1.2318-1.8.9") + minecraft("com.mojang:minecraft:1.8.9") + mappings("de.oceanlabs.mcp:mcp_stable:22-1.8.9") + forge("net.minecraftforge:forge:1.8.9-11.15.1.2318-1.8.9") - if (project.findProperty("neu.buildflags.oneconfig") == "true") { - shadowOnly("cc.polyfrost:oneconfig-wrapper-launchwrapper:1.0.0-beta+") // Should be included in jar - runtimeOnly("cc.polyfrost:oneconfig-wrapper-launchwrapper:1.0.0-beta+") // Should be included in jar - } + if (project.findProperty("neu.buildflags.oneconfig") == "true") { + shadowOnly("cc.polyfrost:oneconfig-wrapper-launchwrapper:1.0.0-beta+") // Should be included in jar + runtimeOnly("cc.polyfrost:oneconfig-wrapper-launchwrapper:1.0.0-beta+") // Should be included in jar + } - "oneconfigCompileOnly"(project(":oneconfigquarantine", configuration = "namedElements")) - "oneconfigImplementation"(sourceSets.main.get().output) - "runtimeOnly"(oneconfigQuarantineSourceSet.output) + "oneconfigCompileOnly"(project(":oneconfigquarantine", configuration = "namedElements")) + "oneconfigImplementation"(sourceSets.main.get().output) + "runtimeOnly"(oneconfigQuarantineSourceSet.output) - // Please keep this version in sync with KotlinLoadingTweaker - implementation(enforcedPlatform("org.jetbrains.kotlin:kotlin-bom:1.8.0")) - kotlinDependencies(kotlin("stdlib")) - kotlinDependencies(kotlin("reflect")) + // Please keep this version in sync with KotlinLoadingTweaker + implementation(enforcedPlatform("org.jetbrains.kotlin:kotlin-bom:1.8.0")) + kotlinDependencies(kotlin("stdlib")) + kotlinDependencies(kotlin("reflect")) - ksp("dev.zacsweers.autoservice:auto-service-ksp:1.0.0") - implementation("com.google.auto.service:auto-service-annotations:1.0.1") + ksp("dev.zacsweers.autoservice:auto-service-ksp:1.0.0") + implementation("com.google.auto.service:auto-service-annotations:1.0.1") - compileOnly(ksp(project(":annotations"))!!) - compileOnly("org.projectlombok:lombok:1.18.24") - annotationProcessor("org.projectlombok:lombok:1.18.24") - "oneconfigAnnotationProcessor"("org.projectlombok:lombok:1.18.24") + compileOnly(ksp(project(":annotations"))!!) + compileOnly("org.projectlombok:lombok:1.18.24") + annotationProcessor("org.projectlombok:lombok:1.18.24") + "oneconfigAnnotationProcessor"("org.projectlombok:lombok:1.18.24") - shadowImplementation("com.mojang:brigadier:1.0.18") + shadowImplementation("com.mojang:brigadier:1.0.18") + shadowImplementation("moe.nea:libautoupdate:1.2.0") - mixinRTDependencies("org.spongepowered:mixin:0.7.11-SNAPSHOT") { - isTransitive = false // Dependencies of mixin are already bundled by minecraft - } - annotationProcessor("net.fabricmc:sponge-mixin:0.11.4+mixin.0.8.5") - compileOnly("org.jetbrains:annotations:24.0.1") - - modImplementation(libs.moulconfig) - shadowOnly(libs.moulconfig) - - @Suppress("VulnerableLibrariesLocal") - shadowApi("info.bliki.wiki:bliki-core:3.1.0") - testImplementation("org.junit.jupiter:junit-jupiter:5.9.2") - testAnnotationProcessor("net.fabricmc:sponge-mixin:0.11.4+mixin.0.8.5") - detektPlugins("org.notenoughupdates:detektrules:1.0.0") - devEnv("me.djtheredstoner:DevAuth-forge-legacy:1.1.0") + mixinRTDependencies("org.spongepowered:mixin:0.7.11-SNAPSHOT") { + isTransitive = false // Dependencies of mixin are already bundled by minecraft + } + annotationProcessor("net.fabricmc:sponge-mixin:0.11.4+mixin.0.8.5") + compileOnly("org.jetbrains:annotations:24.0.1") + + modImplementation(libs.moulconfig) + shadowOnly(libs.moulconfig) + + @Suppress("VulnerableLibrariesLocal") + shadowApi("info.bliki.wiki:bliki-core:3.1.0") + testImplementation("org.junit.jupiter:junit-jupiter:5.9.2") + testAnnotationProcessor("net.fabricmc:sponge-mixin:0.11.4+mixin.0.8.5") + detektPlugins("org.notenoughupdates:detektrules:1.0.0") + devEnv("me.djtheredstoner:DevAuth-forge-legacy:1.1.0") } java { - withSourcesJar() - toolchain.languageVersion.set(JavaLanguageVersion.of(8)) + withSourcesJar() + toolchain.languageVersion.set(JavaLanguageVersion.of(8)) } // Tasks: tasks.withType(JavaCompile::class) { - options.encoding = "UTF-8" - options.isFork = true + options.encoding = "UTF-8" + options.isFork = true } tasks.named("compileOneconfigJava", JavaCompile::class) { - doFirst { - println("oneconfig args: ${this@named.options.compilerArgs}") - } + doFirst { + println("oneconfig args: ${this@named.options.compilerArgs}") + } } tasks.named<Test>("test") { - useJUnitPlatform() - systemProperty("junit.jupiter.extensions.autodetection.enabled", "true") - this.javaLauncher.set(javaToolchains.launcherFor(java.toolchain)) + useJUnitPlatform() + systemProperty("junit.jupiter.extensions.autodetection.enabled", "true") + this.javaLauncher.set(javaToolchains.launcherFor(java.toolchain)) + testLogging { + exceptionFormat = TestExceptionFormat.FULL + } } +val badJars = layout.buildDirectory.dir("badjars") tasks.named("jar", Jar::class) { - from(oneconfigQuarantineSourceSet.output) + from(oneconfigQuarantineSourceSet.output) + archiveClassifier.set("named") + destinationDirectory.set(badJars) } tasks.withType(Jar::class) { - archiveBaseName.set("NotEnoughUpdates") - manifest.attributes.run { - this["Main-Class"] = "NotSkyblockAddonsInstallerFrame" - this["TweakClass"] = "io.github.moulberry.notenoughupdates.loader.NEUDelegatingTweaker" - this["MixinConfigs"] = "mixins.notenoughupdates.json" - this["FMLCorePluginContainsFMLMod"] = "true" - this["ForceLoadAsMod"] = "true" - this["Manifest-Version"] = "1.0" - this["FMLAT"] = "accesstransformer.cfg" - } + archiveBaseName.set("NotEnoughUpdates") + manifest.attributes.run { + this["Main-Class"] = "NotSkyblockAddonsInstallerFrame" + this["TweakClass"] = "io.github.moulberry.notenoughupdates.loader.NEUDelegatingTweaker" + this["MixinConfigs"] = "mixins.notenoughupdates.json" + this["FMLCorePluginContainsFMLMod"] = "true" + this["ForceLoadAsMo |
