diff --git a/.github/workflows/announce-release-on-discord.yml b/.github/workflows/announce-release-on-discord.yml index 77fa897323..61038e9a3a 100644 --- a/.github/workflows/announce-release-on-discord.yml +++ b/.github/workflows/announce-release-on-discord.yml @@ -24,5 +24,5 @@ jobs: "" "The download is available at:" "- Spigot: " - "- Modrinth: " + "- Modrinth: " "- CurseForge: " diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 7b578480f8..8766c697b2 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -24,4 +24,4 @@ jobs: uses: actions/upload-artifact@v3 with: name: FastAsyncWorldEdit-SNAPSHOT - path: worldedit-bukkit/build/libs/FastAsyncWorldEdit-Bukkit-*.jar + path: worldedit-bukkit/build/libs/FastAsyncWorldEdit-*.jar diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 79aa448d8d..a24529c9e2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -70,9 +70,9 @@ jobs: uses: actions/upload-artifact@v3 with: name: FastAsyncWorldEdit-Bukkit-SNAPSHOT - path: worldedit-bukkit/build/libs/FastAsyncWorldEdit-Bukkit-*.jar + path: worldedit-bukkit/build/libs/FastAsyncWorldEdit-*.jar - name: Publish to Modrinth if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/main'}} - run: ./gradlew modrinth + run: ./gradlew publishMods env: MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} diff --git a/.github/workflows/upload-release-assets.yml b/.github/workflows/upload-release-assets.yml index c6e0ea2cf0..ea012486c8 100644 --- a/.github/workflows/upload-release-assets.yml +++ b/.github/workflows/upload-release-assets.yml @@ -21,6 +21,6 @@ jobs: - name: Upload Release Assets uses: AButler/upload-release-assets@v3.0 with: - files: 'worldedit-bukkit/build/libs/FastAsyncWorldEdit-Bukkit-*.jar' + files: 'worldedit-bukkit/build/libs/FastAsyncWorldEdit-*.jar' repo-token: ${{ secrets.GITHUB_TOKEN }} release-tag: ${{ github.event.release.tag_name }} diff --git a/buildSrc/src/main/kotlin/AdapterConfig.kt b/buildSrc/src/main/kotlin/AdapterConfig.kt index 60f9a5733f..1d141621bb 100644 --- a/buildSrc/src/main/kotlin/AdapterConfig.kt +++ b/buildSrc/src/main/kotlin/AdapterConfig.kt @@ -20,4 +20,8 @@ fun Project.applyPaperweightAdapterConfiguration() { tasks.named("assemble") { dependsOn("reobfJar") } + + tasks.named("javadoc") { + enabled = false + } } diff --git a/buildSrc/src/main/kotlin/PlatformConfig.kt b/buildSrc/src/main/kotlin/PlatformConfig.kt index 128e7f09d2..6a2c9d7eea 100644 --- a/buildSrc/src/main/kotlin/PlatformConfig.kt +++ b/buildSrc/src/main/kotlin/PlatformConfig.kt @@ -12,6 +12,7 @@ import org.gradle.kotlin.dsl.named import org.gradle.kotlin.dsl.provideDelegate import org.gradle.kotlin.dsl.register import org.gradle.kotlin.dsl.the +import org.gradle.kotlin.dsl.withType import org.gradle.plugins.signing.SigningExtension fun Project.applyPlatformAndCoreConfiguration() { @@ -132,7 +133,7 @@ fun Project.applyPlatformAndCoreConfiguration() { } fun Project.applyShadowConfiguration() { - tasks.named("shadowJar") { + tasks.withType().configureEach { dependencies { include(project(":worldedit-libs:core")) include(project(":worldedit-libs:${project.name.replace("worldedit-", "")}")) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7c9552c71b..ae83bd4357 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -51,7 +51,7 @@ mockito = "5.14.2" # Gradle plugins pluginyml = "0.6.0" -minotaur = "2.8.7" +mod-publish-plugin = "0.7.4" [libraries] # Minecraft expectations @@ -127,4 +127,4 @@ log4jCore = { group = "org.apache.logging.log4j", name = "log4j-core", version.r [plugins] pluginyml = { id = "net.minecrell.plugin-yml.bukkit", version.ref = "pluginyml" } -minotaur = { id = "com.modrinth.minotaur", version.ref = "minotaur" } +mod-publish-plugin = { id = "me.modmuss50.mod-publish-plugin", version.ref = "mod-publish-plugin" } diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index c438e8ff46..8a9f435564 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -1,9 +1,10 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import io.papermc.paperweight.userdev.attribute.Obfuscation +import me.modmuss50.mpp.ReleaseType plugins { `java-library` - alias(libs.plugins.minotaur) + alias(libs.plugins.mod.publish.plugin) } project.description = "Bukkit" @@ -47,21 +48,26 @@ val localImplementation = configurations.create("localImplementation") { } val adapters = configurations.create("adapters") { - description = "Adapters to include in the JAR" + description = "Adapters to include in the JAR (Mojmap)" isCanBeConsumed = false isCanBeResolved = true shouldResolveConsistentlyWith(configurations["runtimeClasspath"]) attributes { - attribute(Obfuscation.OBFUSCATION_ATTRIBUTE, - if ((project.findProperty("enginehub.obf.none") as String?).toBoolean()) { - objects.named(Obfuscation.NONE) - } else { - objects.named(Obfuscation.OBFUSCATED) - } - ) + attribute(Obfuscation.OBFUSCATION_ATTRIBUTE, objects.named(Obfuscation.NONE)) } } +val adaptersReobf = configurations.create("adaptersReobf") { + description = "Adapters to include in the JAR (Spigot-Mapped)" + isCanBeConsumed = false + isCanBeResolved = true + shouldResolveConsistentlyWith(configurations["runtimeClasspath"]) + attributes { + attribute(Obfuscation.OBFUSCATION_ATTRIBUTE, objects.named(Obfuscation.OBFUSCATED)) + } + extendsFrom(adapters) +} + dependencies { // Modules api(projects.worldeditCore) @@ -141,9 +147,37 @@ tasks.named("jar") { addJarManifest(WorldEditKind.Plugin, includeClasspath = true) +tasks.register("reobfShadowJar") { + archiveFileName.set("${rootProject.name}-Bukkit-${project.version}.${archiveExtension.getOrElse("jar")}") + configurations = listOf( + project.configurations.runtimeClasspath.get(), // as is done by shadow for the default shadowJar + adaptersReobf + ) + + // as is done by shadow for the default shadowJar + from(sourceSets.main.map { it.output }) + manifest.inheritFrom(tasks.jar.get().manifest) + exclude("META-INF/INDEX.LIST", "META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA", "module-info.class") + + manifest { + attributes( + "FAWE-Plugin-Jar-Type" to "spigot" + ) + } +} + tasks.named("shadowJar") { + archiveFileName.set("${rootProject.name}-Paper-${project.version}.${archiveExtension.getOrElse("jar")}") configurations.add(adapters) - archiveFileName.set("${rootProject.name}-Bukkit-${project.version}.${archiveExtension.getOrElse("jar")}") + manifest { + attributes( + "paperweight-mappings-namespace" to "mojang", + "FAWE-Plugin-Jar-Type" to "mojang" + ) + } +} + +tasks.withType().configureEach { dependencies { // In tandem with not bundling log4j, we shouldn't relocate base package here. // relocate("org.apache.logging", "com.sk89q.worldedit.log4j") @@ -198,20 +232,51 @@ tasks.named("shadowJar") { tasks.named("assemble").configure { dependsOn("shadowJar") + dependsOn("reobfShadowJar") } -tasks { - modrinth { - token.set(System.getenv("MODRINTH_TOKEN")) +publishMods { + displayName.set("${project.version}") + version.set("${project.version}") + type.set(ReleaseType.STABLE) + changelog.set("The changelog is available on GitHub: https://github.com/IntellectualSites/" + + "FastAsyncWorldEdit/releases/tag/${project.version}") + + val common = modrinthOptions { + accessToken.set(System.getenv("MODRINTH_TOKEN")) projectId.set("fastasyncworldedit") - versionName.set("${project.version}") - versionNumber.set("${project.version}") - versionType.set("release") - uploadFile.set(file("build/libs/${rootProject.name}-Bukkit-${project.version}.jar")) - gameVersions.addAll(listOf("1.20.2", "1.20.4", "1.20.6", "1.21.1", "1.21.3")) - loaders.addAll(listOf("paper", "spigot")) - changelog.set("The changelog is available on GitHub: https://github.com/IntellectualSites/" + - "FastAsyncWorldEdit/releases/tag/${project.version}") - syncBodyFrom.set(rootProject.file("README.md").readText()) + projectDescription.set(rootProject.file("README.md").readText()) } + + // We publish the reobfJar twice to ensure that the modrinth download menu picks the right jar for the platform regardless + // of minecraft version. + + val mojmapPaperVersions = listOf("1.20.6", "1.21.1", "1.21.3") + val spigotMappedPaperVersions = listOf("1.20.2", "1.20.4") + + // Mark reobfJar as spigot only for 1.20.5+ + modrinth("spigot") { + from(common) + file.set(tasks.named("reobfShadowJar").flatMap { it.archiveFile }) + minecraftVersions.set(mojmapPaperVersions) + modLoaders.set(listOf("spigot")) + } + + // Mark reobfJar as spigot & paper for <1.20.5 + modrinth("spigotAndOldPaper") { + from(common) + file.set(tasks.named("reobfShadowJar").flatMap { it.archiveFile }) + minecraftVersions.set(spigotMappedPaperVersions) + modLoaders.set(listOf("paper", "spigot")) + } + + // Mark mojang mapped jar as paper 1.20.5+ only + modrinth { + from(common) + file.set(tasks.named("shadowJar").flatMap { it.archiveFile }) + minecraftVersions.set(mojmapPaperVersions) + modLoaders.set(listOf("paper")) + } + + // dryRun.set(true) // For testing } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java index f676ae07b3..c11f8bd73b 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java @@ -32,9 +32,11 @@ import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditManifest; import com.sk89q.worldedit.bukkit.adapter.AdapterLoadException; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.BukkitImplLoader; +import com.sk89q.worldedit.bukkit.adapter.Refraction; import com.sk89q.worldedit.event.platform.CommandEvent; import com.sk89q.worldedit.event.platform.CommandSuggestionEvent; import com.sk89q.worldedit.event.platform.PlatformReadyEvent; @@ -90,7 +92,9 @@ import java.nio.file.Paths; import java.util.List; import java.util.Locale; +import java.util.Objects; import java.util.Optional; +import java.util.jar.Attributes; import static com.google.common.base.Preconditions.checkNotNull; import static com.sk89q.worldedit.internal.anvil.ChunkDeleter.DELCHUNKS_FILE_NAME; @@ -131,6 +135,50 @@ public void onLoad() { } } //FAWE end + //FAWE start + final Attributes attributes = WorldEditManifest.readAttributes(); + Objects.requireNonNull(attributes, "Could not retrieve manifest attributes"); + final String type = attributes.getValue("FAWE-Plugin-Jar-Type"); + Objects.requireNonNull(type, "Could not determine plugin jar type"); + if (PaperLib.isPaper()) { + if (PaperLib.getMinecraftVersion() < 20 || (PaperLib.getMinecraftVersion() == 20 && PaperLib.getMinecraftPatchVersion() < 5)) { + if (type.equals("mojang") && !Refraction.isMojangMapped()) { + throw new IllegalStateException( + """ + + ********************************************** + ** You are using the wrong FAWE jar for your Minecraft version. + ** Download the correct FAWE jar from Modrinth: https://modrinth.com/plugin/fastasyncworldedit/ + **********************************************""" + ); + } + } else if (PaperLib.getMinecraftVersion() > 20 || (PaperLib.getMinecraftVersion() == 20 && PaperLib.getMinecraftPatchVersion() >= 5)) { + if (type.equals("spigot")) { + LOGGER.warn( + """ + + ********************************************** + ** You are using the Spigot-mapped FAWE jar on a modern Paper version. + ** This will result in slower first-run times and wasted disk space from plugin remapping. + ** Download the Paper FAWE jar from Modrinth to avoid this: https://modrinth.com/plugin/fastasyncworldedit/ + **********************************************""" + ); + } + } + } else { + if (type.equals("mojang")) { + throw new IllegalStateException( + """ + + ********************************************** + ** You are attempting to run the Paper FAWE jar on a Spigot server. + ** Either switch to Paper (https://papermc.io), or download the correct FAWE jar for your platform + ** from Modrinth: https://modrinth.com/plugin/fastasyncworldedit/ + **********************************************""" + ); + } + } + //FAWE end INSTANCE = this; diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/Refraction.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/Refraction.java index 025700ace1..2738531863 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/Refraction.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/Refraction.java @@ -42,6 +42,10 @@ public static String pickName(String mojangName, String spigotName) { return IS_MOJANG_MAPPED ? mojangName : spigotName; } + public static boolean isMojangMapped() { + return IS_MOJANG_MAPPED; + } + private Refraction() { } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEditManifest.java b/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEditManifest.java index 449e08db3d..c7ffa7769c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEditManifest.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEditManifest.java @@ -64,7 +64,7 @@ public static WorldEditManifest load() { } @Nullable - private static Attributes readAttributes() { + public static Attributes readAttributes() { Class clazz = WorldEditManifest.class; String className = clazz.getSimpleName() + ".class"; String classPath = clazz.getResource(className).toString();