diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e00871d..6089b28 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -80,23 +80,31 @@ jobs: - name: Publish to Modrinth env: MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} - run: ./gradlew build modrinth modrinthSyncBody + run: ./gradlew modrinthSyncBody :mod:fabric:modrinth :mod:neoforge:modrinth - name: Publish to GitHub env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | + ./gradlew copySubJars + CHANGELOG='${{ steps.changelog.outputs.changelog }}' NL=$'\n' CHANGELOG=${CHANGELOG//$'\\n'/"${NL}"} echo "$CHANGELOG" >> "notes.txt" gh release create ${{ github.ref_name }} build/libs/**.jar --notes-file notes.txt + - name: Publish to Maven + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + run: ./gradlew publish + - name: Patch Changelog run: ./gradlew patchChangelog - - name: Build Documentation (DokkaHtml) - run: ./gradlew dokkaHtml + - name: Build Documentation (Dokka) + run: ./gradlew dokkaGenerate - name: Create Documentation Pull Request env: @@ -111,7 +119,7 @@ jobs: git checkout -b $BRANCH git add CHANGELOG.md git add docs/ - git commit -m "docs(dokka): patch docs and changelog for $VERSION" + git commit -m "docs: patch docs and changelog for $VERSION" git push -u origin $BRANCH gh pr create \ @@ -130,4 +138,4 @@ jobs: - name: Deploy Dokka Artifact to GitHub Pages id: deployment - uses: actions/deploy-pages@v4 \ No newline at end of file + uses: actions/deploy-pages@v4 diff --git a/CHANGELOG.md b/CHANGELOG.md index bc1c422..375f2f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,14 +7,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- NeoForge runtime target +- (NeoForge) `PayloadRegistrar.netlibPayload` extension function for registering SerializedPayloads with NeoForge networking. +- Created typealiases in `dev.wanderia.netlib.payload.api` for moved classes. + ### Changed +- Renamed Marven artifacts to match targets: `netlib-common`, `netlib-fabric`, `netlib-neoforge` +- Moved `dev.wanderia.netlib.payload.api` classes to `dev.wanderia.netlib.payload` +- Updated `dokka` from `1.9.20` to `2.0.0-Beta` +- Updated `fabric-api` from `0.103.0+1.21.1` to `0.105.0+1.21.1` +- Updated `fabric-kotlin` from `1.12.1+kotlin.2.0.20` to `1.12.2+kotlin.2.0.20` +- Updated `fabric-loader` from `0.16.3` to `0.16.5` +- Updated `kotlinx-serialization` from `1.7.1` to `1.7.3` + ### Deprecated +- Typealiases in `dev.wanderia.netlib.payload.api`, replace with `dev.wanderia.netlib.payload`. + ### Removed +- Testmod, to be added back for each runtime target. + ### Fixed +- Broken dokka versioning plugin configuration. + ### Security ## [1.2.0] - 2024-08-28 diff --git a/README.md b/README.md index 0b9ac4f..7f77acb 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,14 @@ repositories { maven("https://maven.wanderia.dev/releases") { name = "Wanderia" } } dependencies { - include("dev.wanderia:netlib:$version") - modImplementation("dev.wanderia:netlib:$version") + // Fabric + include("dev.wanderia:netlib-fabric:$version") + modImplementation("dev.wanderia:netlib-fabric:$version") + + // NeoForge + jarJar("dev.wanderia:netlib-neoforge:$version") { + jarJar.pin(it, "[$version,)") + } } ``` See the [testmod](https://github.com/wanderia/netlib/tree/main/src/testmod) for example usage. diff --git a/build.gradle.kts b/build.gradle.kts index 518e2ef..d3b2bc8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,136 +1,32 @@ -import org.jetbrains.changelog.Changelog +import com.diffplug.gradle.spotless.SpotlessExtension import org.jetbrains.changelog.ChangelogPluginConstants.SEM_VER_REGEX import org.jetbrains.changelog.date -import org.jetbrains.dokka.base.DokkaBase -import org.jetbrains.dokka.base.DokkaBaseConfiguration -import org.jetbrains.dokka.versioning.VersioningConfiguration -import org.jetbrains.dokka.versioning.VersioningPlugin plugins { - alias(libs.plugins.kotlin) - alias(libs.plugins.loom) - alias(libs.plugins.kotlin.serialization) - alias(libs.plugins.spotless) + alias(libs.plugins.kotlin) apply false + alias(libs.plugins.loom) apply false + alias(libs.plugins.kotlin.serialization) apply false + alias(libs.plugins.spotless) apply false alias(libs.plugins.changelog) - alias(libs.plugins.dokka) + alias(libs.plugins.dokka) apply false + alias(libs.plugins.dokka.javadoc) apply false alias(libs.plugins.minotaur) alias(libs.plugins.kotlinx.kover) - `maven-publish` -} - -buildscript { - dependencies { - classpath(libs.dokka.pluginBase) - classpath(libs.dokka.pluginVersioning) - } + alias(libs.plugins.loader.common) apply false + alias(libs.plugins.loader.dokka) apply false + alias(libs.plugins.loader.runtime) apply false } group = "dev.wanderia" - -version = "1.2.0" +version = "1.3.0" repositories { mavenCentral() } dependencies { - minecraft(libs.minecraft) - mappings(loom.officialMojangMappings()) - modImplementation(libs.fabric.kotlin) - modImplementation(libs.fabric.loader) - modImplementation(fabricApi.module("fabric-networking-api-v1", libs.versions.fabricApi.get())) - implementation(libs.kotlinx.serializationCore) - - testImplementation(libs.kotlin.test) - testImplementation(libs.kotlin.test.junit5) - testImplementation(libs.junit.params) -} - -tasks { - processResources { - inputs.property("version", project.version) - filesMatching("fabric.mod.json") { expand(mutableMapOf("version" to project.version)) } - } - - dokkaHtml { - pluginConfiguration { - customAssets = listOf(file("artSrc/logo-icon.svg")) - footerMessage = "(c) 2024 Wanderia" - } - - val docsVersionDir = projectDir.resolve("docs/version") - val docsVersion = project.version.toString() - val currentDocsDir = docsVersionDir.resolve(docsVersion) - outputDirectory = currentDocsDir - - pluginConfiguration { - version = docsVersion - olderVersionsDir = docsVersionDir - } - - doLast { - currentDocsDir.copyRecursively(file("docs-publishing/"), overwrite = true) - currentDocsDir.resolve("older").deleteRecursively() - } - } - - val dokkaJar by - registering(Jar::class) { - from(dokkaHtml) - dependsOn(dokkaHtml) - archiveClassifier = "javadoc" - } - - jar { from("LICENSE") { rename { "${it}_${project.base.archivesName.get()}" } } } - - test { useJUnitPlatform() } -} - -val enableDCEVM: Boolean = - if (System.getProperty("java.vendor") == "JetBrains s.r.o.") { - println("JetBrains Runtime found, enabling Enhanced Class Redefinition (DCEVM)") - true - } else { - false - } - -val testmod: SourceSet by - sourceSets.creating { - compileClasspath += sourceSets.main.get().compileClasspath - compileClasspath += sourceSets.main.get().output - runtimeClasspath += sourceSets.main.get().runtimeClasspath - runtimeClasspath += sourceSets.main.get().output - } - -loom { - runtimeOnlyLog4j = true - runs { - configureEach { - if (enableDCEVM) { - vmArgs("-XX:+AllowEnhancedClassRedefinition") - } - property("dev.wanderia.netlib.debug", "true") - ideConfigGenerated(name.contains("testmod")) - runDir("runs/$name") - } - - create("testmodClient") { - client() - name = "Testmod Client" - source(testmod) - } - - create("testmodServer") { - server() - name = "Testmod Server" - source(testmod) - } - } - - mods { - create("wanderia-netlib") { sourceSet(sourceSets.main.get()) } - - create("testmod") { sourceSet(testmod) } - } + kover(projects.mod.common) + kover(projects.mod.fabric) + kover(projects.mod.neoforge) } changelog { @@ -146,103 +42,41 @@ changelog { combinePreReleases = true } -kotlin { - jvmToolchain(21) - explicitApi() -} - -java { - withSourcesJar() - targetCompatibility = JavaVersion.VERSION_21 - sourceCompatibility = JavaVersion.VERSION_21 -} - modrinth { token = System.getenv("MODRINTH_TOKEN") debugMode = System.getenv("MODRINTH_DEBUG") == "1" - projectId = "netlib" - versionNumber = project.version.toString() - versionType = - with(project.version.toString()) { - when { - contains("alpha") -> "alpha" - contains("beta") -> "beta" - else -> "release" - } - } - uploadFile.set(tasks.remapJar) - additionalFiles.set(listOf(tasks.remapSourcesJar)) - gameVersions = listOf(libs.versions.minecraft.get()) - dependencies { - required.project("fabric-api") - required.project("fabric-language-kotlin") - } - changelog = - rootProject.changelog.renderItem( - rootProject.changelog.getUnreleased().withEmptySections(false).withHeader(false), - Changelog.OutputType.MARKDOWN, - ) syncBodyFrom = rootProject.file("README.md").readText() } -spotless { - kotlin { - ktfmt().kotlinlangStyle() - licenseHeaderFile("$projectDir/HEADER") - } - kotlinGradle { ktfmt().kotlinlangStyle() } - java { - googleJavaFormat() - licenseHeaderFile("$projectDir/HEADER") - } -} - -publishing { - publications { - create("maven") { - pom { - name = "netlib" - description = "netlib $version - Kotlinx Serialization for custom payloads." - url = "https://github.com/wanderia/netlib" - licenses { - license { - name = "Mozilla Public License v2.0" - url = "https://www.mozilla.org/en-US/MPL/2.0/" - } - } - developers { - developer { - name = "Pyrrha Wills" - id = "JustPyrrha" - email = "contact@pyrrha.gay" - } - } - scm { - connection = "scm:git:git://github.com/wanderia/netlib.git" - developerConnection = "scm:git:ssh://github.com:wanderia/netlib.git" - url = "https://github.com/wanderia/netlib/tree/main" - } +subprojects { + if (!project.name.endsWith("mod") && project.name != "docs") { + apply(plugin = "com.diffplug.spotless") + extensions.configure { + kotlin { + ktfmt().kotlinlangStyle() + licenseHeaderFile("${rootProject.projectDir}/HEADER") + } + kotlinGradle { ktfmt().kotlinlangStyle() } + java { + googleJavaFormat() + licenseHeaderFile("${rootProject.projectDir}/HEADER") } - artifact(tasks.remapJar) - artifact(tasks.remapSourcesJar) - artifact(tasks["dokkaJar"]) } } - repositories { - val repositoryUrl = - with(project.version.toString()) { - when { - contains("alpha") || contains("beta") -> "s3://maven.wanderia.dev/snapshots" - else -> "s3://maven.wanderia.dev/releases" - } - } + group = rootProject.group + version = rootProject.version +} - maven(repositoryUrl) { - credentials(AwsCredentials::class) { - accessKey = System.getenv("AWS_ACCESS_KEY_ID") - secretKey = System.getenv("AWS_SECRET_ACCESS_KEY") - } - } +tasks { + val copySubJars by registering(Copy::class) { + dependsOn( + ":mod:common:build", + ":mod:fabric:build", + ":mod:neoforge:build", + ":docs:dokkaHtmlJar" + ) + from(rootProject.subprojects.map { it.layout.buildDirectory.file("libs/").get().asFile }) + into(rootProject.layout.buildDirectory.dir("libs")) } } diff --git a/buildLogic/build.gradle.kts b/buildLogic/build.gradle.kts new file mode 100644 index 0000000..8a8920c --- /dev/null +++ b/buildLogic/build.gradle.kts @@ -0,0 +1,30 @@ +plugins { + `kotlin-dsl` +} + +repositories { + mavenCentral() + gradlePluginPortal() +} + +dependencies { + compileOnly(libs.kotlin.gradlePlugin) + implementation(libs.dokka.gradlePlugin) +} + +gradlePlugin { + plugins { + val loaderCommonPlugin by creating { + id = "loader-common" + implementationClass = "LoaderCommonPlugin" + } + val loaderDokkaPlugin by creating { + id = "loader-dokka" + implementationClass = "LoaderDokkaPlugin" + } + val loaderTargetPlugin by creating { + id = "loader-runtime" + implementationClass = "LoaderRuntimePlugin" + } + } +} diff --git a/buildLogic/settings.gradle.kts b/buildLogic/settings.gradle.kts new file mode 100644 index 0000000..11e3984 --- /dev/null +++ b/buildLogic/settings.gradle.kts @@ -0,0 +1,8 @@ +rootProject.name = "buildLogic" +dependencyResolutionManagement { + versionCatalogs { + val libs by creating { + from(files("../libs.versions.toml")) + } + } +} diff --git a/buildLogic/src/main/kotlin/LoaderCommonPlugin.kt b/buildLogic/src/main/kotlin/LoaderCommonPlugin.kt new file mode 100644 index 0000000..ae391a3 --- /dev/null +++ b/buildLogic/src/main/kotlin/LoaderCommonPlugin.kt @@ -0,0 +1,47 @@ +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.plugins.BasePluginExtension +import org.gradle.api.plugins.JavaPluginExtension +import org.gradle.jvm.toolchain.JavaLanguageVersion +import org.gradle.kotlin.dsl.assign +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.repositories +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension + +class LoaderCommonPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + pluginManager.apply("org.jetbrains.kotlin.jvm") + + extensions.configure { + archivesName = "${rootProject.name}-${project.name}" + } + + extensions.configure { + toolchain.languageVersion.set(JavaLanguageVersion.of(21)) + withSourcesJar() + } + repositories { + mavenCentral() + } + + extensions.configure { + jvmToolchain(21) + explicitApi() + } + + listOf( + "apiElements", + "mainSourceElements", + "runtimeElements", + ).forEach { variant -> + configurations.named(variant) { + outgoing { + capability("dev.wanderia:netlib-${project.name}:$version") + capability("dev.wanderia:netlib:$version") + } + } + } + } + } +} diff --git a/buildLogic/src/main/kotlin/LoaderDokkaPlugin.kt b/buildLogic/src/main/kotlin/LoaderDokkaPlugin.kt new file mode 100644 index 0000000..260a3c5 --- /dev/null +++ b/buildLogic/src/main/kotlin/LoaderDokkaPlugin.kt @@ -0,0 +1,23 @@ +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import org.jetbrains.dokka.gradle.DokkaExtension + +class LoaderDokkaPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + pluginManager.apply("org.jetbrains.dokka") + + + extensions.configure { + // todo: exclude testmod sources + dokkaSourceSets.configureEach { + sourceLink { + remoteUrl("https://github.com/wanderia/netlib") + localDirectory.set(rootDir) + } + } + } + } + } +} diff --git a/buildLogic/src/main/kotlin/LoaderRuntimePlugin.kt b/buildLogic/src/main/kotlin/LoaderRuntimePlugin.kt new file mode 100644 index 0000000..e8022d4 --- /dev/null +++ b/buildLogic/src/main/kotlin/LoaderRuntimePlugin.kt @@ -0,0 +1,65 @@ +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.tasks.compile.JavaCompile +import org.gradle.jvm.tasks.Jar +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.project +import org.gradle.kotlin.dsl.withType +import org.gradle.language.jvm.tasks.ProcessResources +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +class LoaderRuntimePlugin : Plugin { + override fun apply(target: Project) { + with(target) { + pluginManager.apply("loader-common") + + val commonKotlin = configurations.create("commonKotlin") { + isCanBeResolved = true + } + + val commonJava = configurations.create("commonJava") { + isCanBeResolved = true + } + + val commonResources = configurations.create("commonResources") { + isCanBeResolved = true + } + + dependencies { + "compileOnly"(project(path = ":mod:common")) { + capabilities { + requireCapability("dev.wanderia:netlib") + } + } + + commonKotlin(project(path = ":mod:common", configuration = "commonKotlin")) + commonJava(project(path = ":mod:common", configuration = "commonJava")) + commonResources(project(path = ":mod:common", configuration = "commonResources")) + } + + tasks.withType { + dependsOn(commonKotlin) + source(commonKotlin) + } + + tasks.withType { + dependsOn(commonJava) + source(commonJava) + } + + tasks.withType { + dependsOn(commonResources) + from(commonResources) + } + + tasks.named("sourcesJar", Jar::class.java) { + dependsOn(commonKotlin) + from(commonKotlin) + dependsOn(commonJava) + from(commonJava) + dependsOn(commonResources) + from(commonResources) + } + } + } +} diff --git a/docs/build.gradle.kts b/docs/build.gradle.kts new file mode 100644 index 0000000..e4d3aa0 --- /dev/null +++ b/docs/build.gradle.kts @@ -0,0 +1,61 @@ +plugins { + alias(libs.plugins.loader.dokka) + alias(libs.plugins.dokka.javadoc) +} + +repositories { + mavenCentral() +} + +dependencies { + dokka(projects.mod.common) + dokka(projects.mod.fabric) + dokka(projects.mod.neoforge) + + dokkaHtmlPlugin(libs.dokka.versioning) +} + +dokka { + moduleName = "netlib" + + pluginsConfiguration { + versioning { + version = rootProject.version.toString() + olderVersionsDir = layout.projectDirectory.dir("version") + } + + html { + customAssets.from(rootProject.file("artSrc/logo-icon.svg")) + footerMessage = "(c) 2024 Wanderia" + } + } +} + +tasks { + dokkaGenerate { + doLast { + val output = layout.buildDirectory.dir("dokka/html").get().asFile + val versions = layout.projectDirectory.dir("version") + output.copyRecursively(rootProject.file("docs-publishing/"), overwrite = true) + + output.resolve("older/").deleteRecursively() + output.copyRecursively(versions.dir(rootProject.version.toString()).asFile) + } + } + + val dokkaHtmlJar by registering(Jar::class) { + description = "A HTML Documentation JAR containing Dokka HTML" + from(dokkaGeneratePublicationHtml.flatMap { it.outputDirectory }) + archiveClassifier.set("html-doc") + + destinationDirectory.set(layout.buildDirectory.dir("libs")) + archiveBaseName.set("netlib") + archiveVersion.set(rootProject.version.toString()) + } + +// val dokkaJavadocJar by registering(Jar::class) { +// description = "A Javadoc JAR containing Dokka Javadoc" +// from(dokkaGeneratePublicationJavadoc.flatMap { it.outputDirectory }) +// archiveClassifier.set("javadoc") +// } +} diff --git a/docs/version/1.1.0/version.json b/docs/version/1.1.0/version.json new file mode 100644 index 0000000..ae48fc9 --- /dev/null +++ b/docs/version/1.1.0/version.json @@ -0,0 +1 @@ +{"version": "1.1.0"} \ No newline at end of file diff --git a/docs/version/1.2.0/version.json b/docs/version/1.2.0/version.json new file mode 100644 index 0000000..fe8a7ca --- /dev/null +++ b/docs/version/1.2.0/version.json @@ -0,0 +1 @@ +{"version": "1.2.0"} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 40e43aa..f4eeac9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,10 @@ org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=1G org.gradle.parallel=true org.gradle.caching=true -kotlin.code.style=official \ No newline at end of file + +kotlin.code.style=official + +fabric.loom.multiProjectOptimisation=true + +org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled +org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a441313..df97d72 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/libs.versions.toml b/libs.versions.toml index 916bbfb..02cd021 100644 --- a/libs.versions.toml +++ b/libs.versions.toml @@ -1,35 +1,50 @@ [versions] -dokka = "1.9.20" # https://github.com/Kotlin/dokka/releases +dokka = "2.0.0-Beta" # https://github.com/Kotlin/dokka/releases changelog = "2.2.1" # https://github.com/JetBrains/gradle-changelog-plugin/releases -fabricApi = "0.103.0+1.21.1" # https://github.com/FabricMC/fabric/releases -fabricKotlin = "1.12.1+kotlin.2.0.20" # https://github.com/FabricMC/fabric-language-kotlin/releases -fabricLoader = "0.16.3" # https://github.com/FabricMC/fabric-loader/releases +fabricApi = "0.105.0+1.21.1" # https://github.com/FabricMC/fabric/releases +fabricKotlin = "1.12.2+kotlin.2.0.20" # https://github.com/FabricMC/fabric-language-kotlin/releases +fabricLoader = "0.16.5" # https://github.com/FabricMC/fabric-loader/releases fabricLoom = "1.7-SNAPSHOT" # https://github.com/FabricMC/fabric-loom/releases junit-params = "5.10.1" # check which version of junit-jupiter-api/engine kotlin-test adds kotlin = "2.0.20" +kotlinforforge = "5.5.0" # https://github.com/thedarkcolour/KotlinForForge/tree/site/thedarkcolour/kotlinforforge-neoforge kotlinx-kover = "0.8.3" # https://github.com/Kotlin/kotlinx-kover/releases -kotlinxSerialization = "1.7.1" # https://github.com/Kotlin/kotlinx.serialization/releases +kotlinxSerialization = "1.7.3" # https://github.com/Kotlin/kotlinx.serialization/releases minecraft = "1.21.1" +neoForge = "21.1.66" # https://projects.neoforged.net/neoforged/neoforge +neoGradle = "7.0.165" # https://projects.neoforged.net/neoforged/neogradle minotaur = "2.8.7" # https://github.com/modrinth/minotaur/releases +parchment = "2024.07.28" # https://parchmentmc.org/docs/getting-started spotless = "7.0.0.BETA2" # https://github.com/diffplug/spotless/blob/main/plugin-gradle/CHANGES.md [libraries] -dokka-pluginBase = { group = "org.jetbrains.dokka", name = "dokka-base", version.ref = "dokka" } -dokka-pluginVersioning = { group = "org.jetbrains.dokka", name = "versioning-plugin", version.ref = "dokka" } +dokka-gradlePlugin = { group = "org.jetbrains.dokka", name = "dokka-gradle-plugin", version.ref = "dokka" } +dokka-versioning = { group = "org.jetbrains.dokka", name = "versioning-plugin" } fabric-kotlin = { group = "net.fabricmc", name = "fabric-language-kotlin", version.ref = "fabricKotlin" } fabric-loader = { group = "net.fabricmc", name = "fabric-loader", version.ref = "fabricLoader" } junit-params = { group = "org.junit.jupiter", name = "junit-jupiter-params", version.ref = "junit-params" } +kotlinforforge = { group = "thedarkcolour", name = "kotlinforforge-neoforge", version.ref = "kotlinforforge" } +kotlin-gradlePlugin = { group = "org.jetbrains.kotlin.jvm", name = "org.jetbrains.kotlin.jvm.gradle.plugin", version.ref = "kotlin" } kotlin-test = { group = "org.jetbrains.kotlin", name = "kotlin-test" } kotlin-test-junit5 = { group = "org.jetbrains.kotlin", name = "kotlin-test-junit5" } kotlinx-serializationCore = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-core", version.ref = "kotlinxSerialization" } minecraft = { group = "com.mojang", name = "minecraft", version.ref = "minecraft" } +neoforge = { group = "net.neoforged", name = "neoforge", version.ref = "neoForge" } +parchment-fabric = { group = "org.parchmentmc.data", name = "parchment-1.21", version.ref = "parchment" } [plugins] changelog = { id = "org.jetbrains.changelog", version.ref = "changelog" } dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } +dokka-javadoc = { id = "org.jetbrains.dokka-javadoc", version.ref = "dokka" } kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } kotlinx-kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kotlinx-kover" } loom = { id = "fabric-loom", version.ref = "fabricLoom" } minotaur = { id = "com.modrinth.minotaur", version.ref = "minotaur" } +neogradle = { id = "net.neoforged.gradle.userdev", version.ref = "neoGradle" } spotless = { id = "com.diffplug.spotless", version.ref = "spotless" } + +# custom plugins, in buildLogic/ +loader-common = { id = "loader-common" } +loader-dokka = { id = "loader-dokka" } +loader-runtime = { id = "loader-runtime" } diff --git a/mod/common/build.gradle.kts b/mod/common/build.gradle.kts new file mode 100644 index 0000000..fdddbd9 --- /dev/null +++ b/mod/common/build.gradle.kts @@ -0,0 +1,109 @@ +plugins { + alias(libs.plugins.kotlin) + alias(libs.plugins.kotlin.serialization) + alias(libs.plugins.loader.common) + alias(libs.plugins.loader.dokka) + alias(libs.plugins.kotlinx.kover) + alias(libs.plugins.loom) + `maven-publish` +} + +configurations { + val commonKotlin by creating { + isCanBeResolved = false + isCanBeConsumed = true + } + val commonJava by creating { + isCanBeResolved = false + isCanBeConsumed = true + } + val commonResources by creating { + isCanBeResolved = false + isCanBeConsumed = true + } +} + +repositories { + mavenCentral() + maven("https://maven.parchmentmc.org") { name = "Parchment" } +} + +dependencies { + minecraft(libs.minecraft) + mappings( + loom.layered { + officialMojangMappings() + parchment(variantOf(libs.parchment.fabric) { artifactType("zip") }) + } + ) + + modImplementation(fabricApi.module("fabric-networking-api-v1", libs.versions.fabricApi.get())) + + implementation(libs.kotlinx.serializationCore) + + // testImplementation(libs.kotlin.test) + testImplementation(libs.kotlin.test.junit5) + testImplementation(libs.junit.params) +} + +loom { runtimeOnlyLog4j = true } + +kotlin { explicitApi() } + +tasks { jar { from(rootProject.file("LICENSE")) { rename { "${it}_${rootProject.name}" } } } } + +artifacts { + sourceSets.main.get().kotlin.sourceDirectories.forEach { add("commonKotlin", it) } + add("commonJava", sourceSets.main.get().java.sourceDirectories.singleFile) + add("commonResources", sourceSets.main.get().resources.sourceDirectories.singleFile) +} + +publishing { + publications { + create("maven") { + artifactId = base.archivesName.get() + pom { + name = "netlib-common" + description = "netlib $version - Kotlinx Serialization for custom payloads." + url = "https://github.com/wanderia/netlib" + licenses { + license { + name = "Mozilla Public License v2.0" + url = "https://www.mozilla.org/en-US/MPL/2.0/" + } + } + developers { + developer { + name = "Pyrrha Wills" + id = "JustPyrrha" + email = "contact@pyrrha.gay" + } + } + scm { + connection = "scm:git:git://github.com/wanderia/netlib.git" + developerConnection = "scm:git:ssh://github.com:wanderia/netlib.git" + url = "https://github.com/wanderia/netlib/tree/main" + } + } + artifact(tasks.remapJar) + artifact(tasks.remapSourcesJar) + } + } + + repositories { + val repositoryUrl = + with(project.version.toString()) { + when { + contains("alpha") || contains("beta") -> "s3://maven.wanderia.dev/snapshots" + else -> "s3://maven.wanderia.dev/releases" + } + } + + maven(repositoryUrl) { + credentials(AwsCredentials::class) { + accessKey = System.getenv("AWS_ACCESS_KEY_ID") + secretKey = System.getenv("AWS_SECRET_ACCESS_KEY") + } + } + } +} diff --git a/src/main/kotlin/dev/wanderia/netlib/format/PacketByteBufDecoder.kt b/mod/common/src/main/kotlin/dev/wanderia/netlib/format/ByteBufDecoder.kt similarity index 96% rename from src/main/kotlin/dev/wanderia/netlib/format/PacketByteBufDecoder.kt rename to mod/common/src/main/kotlin/dev/wanderia/netlib/format/ByteBufDecoder.kt index efc03de..f9e28a9 100644 --- a/src/main/kotlin/dev/wanderia/netlib/format/PacketByteBufDecoder.kt +++ b/mod/common/src/main/kotlin/dev/wanderia/netlib/format/ByteBufDecoder.kt @@ -22,7 +22,7 @@ public class PacketByteBufDecoder( private var elementsCount: Int = 0, ) : AbstractDecoder() { private var elementIndex: Int = 0 - override val serializersModule: SerializersModule = WanderiaSerializersModule() + override val serializersModule: SerializersModule = NetlibSerializersModule() override fun decodeBoolean(): Boolean = buf.readBoolean() diff --git a/src/main/kotlin/dev/wanderia/netlib/format/PacketByteBufEncoder.kt b/mod/common/src/main/kotlin/dev/wanderia/netlib/format/ByteBufEncoder.kt similarity index 96% rename from src/main/kotlin/dev/wanderia/netlib/format/PacketByteBufEncoder.kt rename to mod/common/src/main/kotlin/dev/wanderia/netlib/format/ByteBufEncoder.kt index b339180..ef6f234 100644 --- a/src/main/kotlin/dev/wanderia/netlib/format/PacketByteBufEncoder.kt +++ b/mod/common/src/main/kotlin/dev/wanderia/netlib/format/ByteBufEncoder.kt @@ -18,7 +18,7 @@ import net.minecraft.network.FriendlyByteBuf @ExperimentalSerializationApi public class PacketByteBufEncoder(private val buf: FriendlyByteBuf) : AbstractEncoder() { - override val serializersModule: SerializersModule = WanderiaSerializersModule() + override val serializersModule: SerializersModule = NetlibSerializersModule() override fun encodeBoolean(value: Boolean) { buf.writeBoolean(value) diff --git a/src/main/kotlin/dev/wanderia/netlib/format/WanderiaSerializersModule.kt b/mod/common/src/main/kotlin/dev/wanderia/netlib/format/SerializersModule.kt similarity index 63% rename from src/main/kotlin/dev/wanderia/netlib/format/WanderiaSerializersModule.kt rename to mod/common/src/main/kotlin/dev/wanderia/netlib/format/SerializersModule.kt index bd34d33..8195fa6 100644 --- a/src/main/kotlin/dev/wanderia/netlib/format/WanderiaSerializersModule.kt +++ b/mod/common/src/main/kotlin/dev/wanderia/netlib/format/SerializersModule.kt @@ -16,8 +16,20 @@ import kotlinx.serialization.modules.contextual private val module: SerializersModule = SerializersModule { include(EmptySerializersModule()) - contextual(IdentifierSerializer) contextual(UUIDSerializer) + contextual(IdentifierSerializer) } -@Suppress("FunctionName") public fun WanderiaSerializersModule(): SerializersModule = module +/** + * A [SerializersModule] containing contextual serializers for Minecraft related classes. + * + * @see PacketByteBufDecoder + * @see PacketByteBufEncoder + */ +public fun NetlibSerializersModule(): SerializersModule = module + +@Deprecated( + "Renamed", + replaceWith = ReplaceWith("dev.wanderia.netlib.format.NetlibSerializersModule()"), +) +public fun WanderiaSerializersModule(): SerializersModule = NetlibSerializersModule() diff --git a/src/main/kotlin/dev/wanderia/netlib/payload/api/PayloadChannel.kt b/mod/common/src/main/kotlin/dev/wanderia/netlib/payload/PayloadChannel.kt similarity index 93% rename from src/main/kotlin/dev/wanderia/netlib/payload/api/PayloadChannel.kt rename to mod/common/src/main/kotlin/dev/wanderia/netlib/payload/PayloadChannel.kt index af34588..1b51ff8 100644 --- a/src/main/kotlin/dev/wanderia/netlib/payload/api/PayloadChannel.kt +++ b/mod/common/src/main/kotlin/dev/wanderia/netlib/payload/PayloadChannel.kt @@ -5,7 +5,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -package dev.wanderia.netlib.payload.api +package dev.wanderia.netlib.payload public enum class PayloadChannel { /** C2S during the configuration phase. */ diff --git a/src/main/kotlin/dev/wanderia/netlib/payload/api/SerializedPayload.kt b/mod/common/src/main/kotlin/dev/wanderia/netlib/payload/SerializedPayload.kt similarity index 96% rename from src/main/kotlin/dev/wanderia/netlib/payload/api/SerializedPayload.kt rename to mod/common/src/main/kotlin/dev/wanderia/netlib/payload/SerializedPayload.kt index e74b05e..ccd47ec 100644 --- a/src/main/kotlin/dev/wanderia/netlib/payload/api/SerializedPayload.kt +++ b/mod/common/src/main/kotlin/dev/wanderia/netlib/payload/SerializedPayload.kt @@ -5,7 +5,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -package dev.wanderia.netlib.payload.api +package dev.wanderia.netlib.payload import dev.wanderia.netlib.format.decodeFrom import dev.wanderia.netlib.format.encodeTo diff --git a/src/main/kotlin/dev/wanderia/netlib/payload/api/SerializedPayloadConfiguration.kt b/mod/common/src/main/kotlin/dev/wanderia/netlib/payload/SerializedPayloadConfiguration.kt similarity index 95% rename from src/main/kotlin/dev/wanderia/netlib/payload/api/SerializedPayloadConfiguration.kt rename to mod/common/src/main/kotlin/dev/wanderia/netlib/payload/SerializedPayloadConfiguration.kt index 0fbad6d..9818fff 100644 --- a/src/main/kotlin/dev/wanderia/netlib/payload/api/SerializedPayloadConfiguration.kt +++ b/mod/common/src/main/kotlin/dev/wanderia/netlib/payload/SerializedPayloadConfiguration.kt @@ -5,7 +5,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -package dev.wanderia.netlib.payload.api +package dev.wanderia.netlib.payload import kotlinx.serialization.ExperimentalSerializationApi import net.minecraft.network.RegistryFriendlyByteBuf diff --git a/mod/common/src/main/kotlin/dev/wanderia/netlib/payload/api/PayloadChannel.kt b/mod/common/src/main/kotlin/dev/wanderia/netlib/payload/api/PayloadChannel.kt new file mode 100644 index 0000000..73a2f15 --- /dev/null +++ b/mod/common/src/main/kotlin/dev/wanderia/netlib/payload/api/PayloadChannel.kt @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2024 Wanderia - All Rights Reserved + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ +package dev.wanderia.netlib.payload.api + +@Deprecated( + replaceWith = ReplaceWith("dev.wanderia.netlib.payload.PayloadChannel"), + message = "Moved Package", +) +public typealias PayloadChannel = dev.wanderia.netlib.payload.PayloadChannel diff --git a/mod/common/src/main/kotlin/dev/wanderia/netlib/payload/api/SerializedPayload.kt b/mod/common/src/main/kotlin/dev/wanderia/netlib/payload/api/SerializedPayload.kt new file mode 100644 index 0000000..ed97831 --- /dev/null +++ b/mod/common/src/main/kotlin/dev/wanderia/netlib/payload/api/SerializedPayload.kt @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2024 Wanderia - All Rights Reserved + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ +package dev.wanderia.netlib.payload.api + +import kotlinx.serialization.ExperimentalSerializationApi + +@ExperimentalSerializationApi +@Deprecated( + replaceWith = ReplaceWith("dev.wanderia.netlib.payload.SerializedPayload"), + message = "Moved Package", +) +public typealias SerializedPayload = dev.wanderia.netlib.payload.SerializedPayload diff --git a/mod/common/src/main/kotlin/dev/wanderia/netlib/payload/api/SerializedPayloadConfiguration.kt b/mod/common/src/main/kotlin/dev/wanderia/netlib/payload/api/SerializedPayloadConfiguration.kt new file mode 100644 index 0000000..f71bd82 --- /dev/null +++ b/mod/common/src/main/kotlin/dev/wanderia/netlib/payload/api/SerializedPayloadConfiguration.kt @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2024 Wanderia - All Rights Reserved + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ +package dev.wanderia.netlib.payload.api + +import kotlinx.serialization.ExperimentalSerializationApi + +@ExperimentalSerializationApi +@Deprecated( + replaceWith = ReplaceWith("dev.wanderia.netlib.payload.SerializedPayloadConfiguration"), + message = "Moved Package", +) +public typealias SerializedPayloadConfiguration = + dev.wanderia.netlib.payload.SerializedPayloadConfiguration diff --git a/src/main/kotlin/dev/wanderia/netlib/serializers/IdentifierSerializer.kt b/mod/common/src/main/kotlin/dev/wanderia/netlib/serializers/IdentifierSerializer.kt similarity index 100% rename from src/main/kotlin/dev/wanderia/netlib/serializers/IdentifierSerializer.kt rename to mod/common/src/main/kotlin/dev/wanderia/netlib/serializers/IdentifierSerializer.kt diff --git a/src/main/kotlin/dev/wanderia/netlib/serializers/UUIDSerializer.kt b/mod/common/src/main/kotlin/dev/wanderia/netlib/serializers/UUIDSerializer.kt similarity index 100% rename from src/main/kotlin/dev/wanderia/netlib/serializers/UUIDSerializer.kt rename to mod/common/src/main/kotlin/dev/wanderia/netlib/serializers/UUIDSerializer.kt diff --git a/src/test/kotlin/EncodeDecodeTests.kt b/mod/common/src/test/kotlin/EncodeDecodeTests.kt similarity index 99% rename from src/test/kotlin/EncodeDecodeTests.kt rename to mod/common/src/test/kotlin/EncodeDecodeTests.kt index 9626c6d..1fbd59a 100644 --- a/src/test/kotlin/EncodeDecodeTests.kt +++ b/mod/common/src/test/kotlin/EncodeDecodeTests.kt @@ -9,7 +9,7 @@ import dev.wanderia.netlib.format.decodeFrom import dev.wanderia.netlib.format.encodeTo -import dev.wanderia.netlib.payload.api.PayloadChannel +import dev.wanderia.netlib.payload.PayloadChannel import java.util.UUID import java.util.stream.Stream import kotlin.random.Random diff --git a/src/test/kotlin/SerializerTests.kt b/mod/common/src/test/kotlin/SerializerTests.kt similarity index 100% rename from src/test/kotlin/SerializerTests.kt rename to mod/common/src/test/kotlin/SerializerTests.kt diff --git a/src/test/kotlin/SerializersModuleTests.kt b/mod/common/src/test/kotlin/SerializersModuleTests.kt similarity index 100% rename from src/test/kotlin/SerializersModuleTests.kt rename to mod/common/src/test/kotlin/SerializersModuleTests.kt diff --git a/mod/fabric/build.gradle.kts b/mod/fabric/build.gradle.kts new file mode 100644 index 0000000..b0a12b2 --- /dev/null +++ b/mod/fabric/build.gradle.kts @@ -0,0 +1,123 @@ +import org.jetbrains.changelog.Changelog +import org.jetbrains.changelog.ChangelogPluginExtension + +plugins { + alias(libs.plugins.kotlin) + alias(libs.plugins.loader.dokka) + alias(libs.plugins.loader.runtime) + alias(libs.plugins.kotlinx.kover) + alias(libs.plugins.loom) + alias(libs.plugins.minotaur) + `maven-publish` +} + +repositories { maven("https://maven.parchmentmc.org") { name = "Parchment" } } + +dependencies { + minecraft(libs.minecraft) + mappings( + loom.layered { + officialMojangMappings() + parchment(variantOf(libs.parchment.fabric) { artifactType("zip") }) + } + ) + + modImplementation(libs.fabric.kotlin) + modImplementation(libs.fabric.loader) + modImplementation(fabricApi.module("fabric-networking-api-v1", libs.versions.fabricApi.get())) +} + +loom { + runtimeOnlyLog4j = true + + mods { create("wanderia-netlib") { sourceSet(sourceSets.main.get()) } } +} + +tasks { + processResources { + inputs.property("version", project.version) + filesMatching("fabric.mod.json") { expand(mutableMapOf("version" to project.version)) } + } + + jar { from(rootProject.file("LICENSE")) { rename { "${it}_${rootProject.name}" } } } +} + +kotlin { explicitApi() } + +modrinth { + val changelogPlugin = rootProject.extensions.getByType() + token = System.getenv("MODRINTH_TOKEN") + debugMode = System.getenv("MODRINTH_DEBUG") == "1" + projectId = "netlib" + versionNumber = "${project.version}+fabric" + versionType = + with(project.version.toString()) { + when { + contains("alpha") -> "alpha" + contains("beta") -> "beta" + else -> "release" + } + } + uploadFile.set(tasks.remapJar) + additionalFiles.set(listOf(tasks.remapSourcesJar)) + gameVersions = listOf(libs.versions.minecraft.get()) + dependencies { + required.project("fabric-api") + required.project("fabric-language-kotlin") + } + changelog = + changelogPlugin.renderItem( + changelogPlugin.getUnreleased().withEmptySections(false).withHeader(false), + Changelog.OutputType.MARKDOWN, + ) +} + +publishing { + publications { + create("maven") { + artifactId = base.archivesName.get() + pom { + name = "netlib-fabric" + description = "netlib $version - Kotlinx Serialization for custom payloads." + url = "https://github.com/wanderia/netlib" + licenses { + license { + name = "Mozilla Public License v2.0" + url = "https://www.mozilla.org/en-US/MPL/2.0/" + } + } + developers { + developer { + name = "Pyrrha Wills" + id = "JustPyrrha" + email = "contact@pyrrha.gay" + } + } + scm { + connection = "scm:git:git://github.com/wanderia/netlib.git" + developerConnection = "scm:git:ssh://github.com:wanderia/netlib.git" + url = "https://github.com/wanderia/netlib/tree/main" + } + } + artifact(tasks.remapJar) + artifact(tasks.remapSourcesJar) + } + } + + repositories { + val repositoryUrl = + with(project.version.toString()) { + when { + contains("alpha") || contains("beta") -> "s3://maven.wanderia.dev/snapshots" + else -> "s3://maven.wanderia.dev/releases" + } + } + + maven(repositoryUrl) { + credentials(AwsCredentials::class) { + accessKey = System.getenv("AWS_ACCESS_KEY_ID") + secretKey = System.getenv("AWS_SECRET_ACCESS_KEY") + } + } + } +} diff --git a/src/main/kotlin/dev/wanderia/netlib/NetLibEntrypoint.kt b/mod/fabric/src/main/kotlin/dev/wanderia/netlib/NetLibEntrypoint.kt similarity index 89% rename from src/main/kotlin/dev/wanderia/netlib/NetLibEntrypoint.kt rename to mod/fabric/src/main/kotlin/dev/wanderia/netlib/NetLibEntrypoint.kt index 10b10da..b2124db 100644 --- a/src/main/kotlin/dev/wanderia/netlib/NetLibEntrypoint.kt +++ b/mod/fabric/src/main/kotlin/dev/wanderia/netlib/NetLibEntrypoint.kt @@ -7,7 +7,7 @@ */ package dev.wanderia.netlib -import dev.wanderia.netlib.payload.api.SerializedPayloadConfiguration +import dev.wanderia.netlib.payload.SerializedPayloadConfiguration import kotlinx.serialization.ExperimentalSerializationApi public const val ENTRYPOINT_NAME: String = "wanderia-netlib" diff --git a/src/main/kotlin/dev/wanderia/netlib/WanderiaNetLib.kt b/mod/fabric/src/main/kotlin/dev/wanderia/netlib/WanderiaNetLib.kt similarity index 94% rename from src/main/kotlin/dev/wanderia/netlib/WanderiaNetLib.kt rename to mod/fabric/src/main/kotlin/dev/wanderia/netlib/WanderiaNetLib.kt index 0ca22c5..6c7ef95 100644 --- a/src/main/kotlin/dev/wanderia/netlib/WanderiaNetLib.kt +++ b/mod/fabric/src/main/kotlin/dev/wanderia/netlib/WanderiaNetLib.kt @@ -7,9 +7,9 @@ */ package dev.wanderia.netlib -import dev.wanderia.netlib.payload.api.PayloadChannel -import dev.wanderia.netlib.payload.api.SerializedPayload -import dev.wanderia.netlib.payload.api.SerializedPayloadConfiguration +import dev.wanderia.netlib.payload.PayloadChannel +import dev.wanderia.netlib.payload.SerializedPayload +import dev.wanderia.netlib.payload.SerializedPayloadConfiguration import kotlinx.serialization.ExperimentalSerializationApi import net.fabricmc.api.ModInitializer import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry diff --git a/src/main/resources/assets/wanderia-netlib/icon.png b/mod/fabric/src/main/resources/assets/wanderia-netlib/icon.png similarity index 100% rename from src/main/resources/assets/wanderia-netlib/icon.png rename to mod/fabric/src/main/resources/assets/wanderia-netlib/icon.png diff --git a/src/main/resources/fabric.mod.json b/mod/fabric/src/main/resources/fabric.mod.json similarity index 100% rename from src/main/resources/fabric.mod.json rename to mod/fabric/src/main/resources/fabric.mod.json diff --git a/mod/neoforge/build.gradle.kts b/mod/neoforge/build.gradle.kts new file mode 100644 index 0000000..2601a42 --- /dev/null +++ b/mod/neoforge/build.gradle.kts @@ -0,0 +1,107 @@ +import org.jetbrains.changelog.Changelog +import org.jetbrains.changelog.ChangelogPluginExtension + +plugins { + alias(libs.plugins.kotlin) + alias(libs.plugins.loader.dokka) + alias(libs.plugins.loader.runtime) + alias(libs.plugins.kotlinx.kover) + alias(libs.plugins.neogradle) + alias(libs.plugins.minotaur) + `maven-publish` +} + +repositories { + maven("https://thedarkcolour.github.io/KotlinForForge/") { name = "KotlinForForge" } +} + +dependencies { + implementation(libs.neoforge) + implementation(libs.kotlinforforge) +} + +subsystems { parchment { mappingsVersion = libs.versions.parchment.get() } } + +tasks { + processResources { + inputs.property("version", project.version) + filesMatching("neoforge.mods.toml") { expand(mutableMapOf("version" to project.version)) } + } +} + +tasks { jar { from(rootProject.file("LICENSE")) { rename { "${it}_${rootProject.name}" } } } } + +modrinth { + val changelogPlugin = rootProject.extensions.getByType() + token = System.getenv("MODRINTH_TOKEN") + debugMode = System.getenv("MODRINTH_DEBUG") == "1" + projectId = "netlib" + versionNumber = "${project.version}+neoforge" + versionType = + with(project.version.toString()) { + when { + contains("alpha") -> "alpha" + contains("beta") -> "beta" + else -> "release" + } + } + uploadFile.set(tasks.jar) + additionalFiles.set(listOf(tasks.sourcesJar)) + gameVersions = listOf(libs.versions.minecraft.get()) + dependencies { required.project("kotlin-for-forge") } + changelog = + changelogPlugin.renderItem( + changelogPlugin.getUnreleased().withEmptySections(false).withHeader(false), + Changelog.OutputType.MARKDOWN, + ) +} + +publishing { + publications { + create("maven") { + artifactId = base.archivesName.get() + pom { + name = "netlib" + description = "netlib $version - Kotlinx Serialization for custom payloads." + url = "https://github.com/wanderia/netlib" + licenses { + license { + name = "Mozilla Public License v2.0" + url = "https://www.mozilla.org/en-US/MPL/2.0/" + } + } + developers { + developer { + name = "Pyrrha Wills" + id = "JustPyrrha" + email = "contact@pyrrha.gay" + } + } + scm { + connection = "scm:git:git://github.com/wanderia/netlib.git" + developerConnection = "scm:git:ssh://github.com:wanderia/netlib.git" + url = "https://github.com/wanderia/netlib/tree/main" + } + } + artifact(tasks.jar) + artifact(tasks.sourcesJar) + } + } + + repositories { + val repositoryUrl = + with(project.version.toString()) { + when { + contains("alpha") || contains("beta") -> "s3://maven.wanderia.dev/snapshots" + else -> "s3://maven.wanderia.dev/releases" + } + } + + maven(repositoryUrl) { + credentials(AwsCredentials::class) { + accessKey = System.getenv("AWS_ACCESS_KEY_ID") + secretKey = System.getenv("AWS_SECRET_ACCESS_KEY") + } + } + } +} diff --git a/mod/neoforge/src/main/kotlin/dev/wanderia/netlib/Extensions.kt b/mod/neoforge/src/main/kotlin/dev/wanderia/netlib/Extensions.kt new file mode 100644 index 0000000..2d5cf96 --- /dev/null +++ b/mod/neoforge/src/main/kotlin/dev/wanderia/netlib/Extensions.kt @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2024 Wanderia - All Rights Reserved + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ +package dev.wanderia.netlib + +import dev.wanderia.netlib.payload.PayloadChannel.ClientboundConfiguration +import dev.wanderia.netlib.payload.PayloadChannel.ClientboundPlay +import dev.wanderia.netlib.payload.PayloadChannel.ServerboundConfiguration +import dev.wanderia.netlib.payload.PayloadChannel.ServerboundPlay +import dev.wanderia.netlib.payload.SerializedPayload +import dev.wanderia.netlib.payload.SerializedPayloadConfiguration +import kotlinx.serialization.ExperimentalSerializationApi +import net.minecraft.network.FriendlyByteBuf +import net.minecraft.network.codec.StreamCodec +import net.neoforged.neoforge.network.handling.IPayloadHandler +import net.neoforged.neoforge.network.registration.PayloadRegistrar + +/** + * Used to register [SerializedPayload]s with NeoForge's networking during + * [net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent] + * + * See [NeoForge Networking Documentation](https://docs.neoforged.net/docs/networking/payload) + */ +@Suppress("UNCHECKED_CAST") +@ExperimentalSerializationApi +public fun > PayloadRegistrar.netlibPayload( + config: SerializedPayloadConfiguration, + handler: IPayloadHandler, +): PayloadRegistrar { + // i hate this ~py + when (config.channels.size) { + 1 -> { + when (config.channels.first()) { + ServerboundConfiguration -> + configurationToServer( + config.payloadId, + config.payloadCodec as StreamCodec, + handler, + ) + ServerboundPlay -> + playToServer( + config.payloadId, + config.payloadCodec as StreamCodec, + handler, + ) + ClientboundConfiguration -> + configurationToClient( + config.payloadId, + config.payloadCodec as StreamCodec, + handler, + ) + ClientboundPlay -> + playToClient( + config.payloadId, + config.payloadCodec as StreamCodec, + handler, + ) + } + } + 2 -> + with(config.channels) { + when { + contains(ServerboundConfiguration) && contains(ClientboundConfiguration) -> + configurationToServer( + config.payloadId, + config.payloadCodec as StreamCodec, + handler, + ) + contains(ServerboundPlay) && contains(ClientboundPlay) -> + playBidirectional( + config.payloadId, + config.payloadCodec as StreamCodec, + handler, + ) + contains(ServerboundPlay) && contains(ServerboundConfiguration) -> + commonToServer( + config.payloadId, + config.payloadCodec as StreamCodec, + handler, + ) + contains(ClientboundPlay) && contains(ClientboundConfiguration) -> + commonToClient( + config.payloadId, + config.payloadCodec as StreamCodec, + handler, + ) + else -> + throw throw IllegalArgumentException( + "Payload channels for ${config.payloadId.id} incompatible with NeoForge networking." + ) + } + } + 4 -> + commonBidirectional( + config.payloadId, + config.payloadCodec as StreamCodec, + handler, + ) + else -> + throw IllegalArgumentException( + "Payload channels for ${config.payloadId.id} incompatible with NeoForge networking." + ) + } + + return this +} diff --git a/mod/neoforge/src/main/kotlin/dev/wanderia/netlib/WanderiaNetLib.kt b/mod/neoforge/src/main/kotlin/dev/wanderia/netlib/WanderiaNetLib.kt new file mode 100644 index 0000000..f52f743 --- /dev/null +++ b/mod/neoforge/src/main/kotlin/dev/wanderia/netlib/WanderiaNetLib.kt @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2024 Wanderia - All Rights Reserved + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ +package dev.wanderia.netlib + +import kotlinx.serialization.ExperimentalSerializationApi +import net.neoforged.fml.common.EventBusSubscriber +import net.neoforged.fml.common.Mod +import org.apache.logging.log4j.LogManager +import org.jetbrains.annotations.ApiStatus + +@Mod("netlib") +@EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD) +@ExperimentalSerializationApi +@ApiStatus.Internal +public object WanderiaNetLib { + + internal val logger = LogManager.getLogger(WanderiaNetLib::class.java) + + init { + logger.info("trans rights are human rights!") + } +} diff --git a/mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml new file mode 100644 index 0000000..714dd00 --- /dev/null +++ b/mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -0,0 +1,19 @@ +modLoader = "kotlinforforge" +loaderVersion = "[5.5,)" +license = "MPL-2.0" +issueTrackerURL = "https://github.com/wanderia/netlib/issues" + +[[mods]] +modId = "netlib" +version = "$version" +description = ''' +Kotlinx Serialization for custom payloads. +''' +logoFile = "wanderia-netlib.png" +updateJSONURL = "https://api.modrinth.com/updates/netlib/forge_updates.json" +displayURL = "https://modrinth.com/mod/netlib" + +[[dependencies.netlib]] +modId = "minecraft" +type = "required" +versionRange = "[1.21.1,)" diff --git a/mod/neoforge/src/main/resources/wanderia-netlib.png b/mod/neoforge/src/main/resources/wanderia-netlib.png new file mode 100644 index 0000000..aff48c0 Binary files /dev/null and b/mod/neoforge/src/main/resources/wanderia-netlib.png differ diff --git a/settings.gradle.kts b/settings.gradle.kts index fcaec68..ffc9687 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,8 +1,10 @@ rootProject.name = "netlib" pluginManagement { + includeBuild("buildLogic") repositories { maven("https://maven.fabricmc.net/") { name = "FabricMC" } + maven("https://maven.neoforged.net/releases") { name = "NeoForge" } mavenCentral() gradlePluginPortal() } @@ -11,3 +13,12 @@ pluginManagement { dependencyResolutionManagement { versionCatalogs { create("libs") { from(files("libs.versions.toml")) } } } + +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") +include( + ":docs", + + ":mod:common", + ":mod:fabric", + ":mod:neoforge" +) diff --git a/src/testmod/kotlin/NetLibInit.kt b/src/testmod/kotlin/NetLibInit.kt deleted file mode 100644 index babfe17..0000000 --- a/src/testmod/kotlin/NetLibInit.kt +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2024 Wanderia - All Rights Reserved - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ -package dev.wanderia.testmod - -import dev.wanderia.netlib.NetLibEntrypoint -import dev.wanderia.netlib.payload.api.SerializedPayloadConfiguration -import dev.wanderia.testmod.payloads.TestModPayload -import kotlinx.serialization.ExperimentalSerializationApi - -@OptIn(ExperimentalSerializationApi::class) -object NetLibInit : NetLibEntrypoint { - override fun register(register: (List>) -> Unit) { - register(listOf(TestModPayload.Configuration)) - } -} diff --git a/src/testmod/kotlin/TestMod.kt b/src/testmod/kotlin/TestMod.kt deleted file mode 100644 index f044ed3..0000000 --- a/src/testmod/kotlin/TestMod.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2024 Wanderia - All Rights Reserved - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ -package dev.wanderia.testmod - -import dev.wanderia.netlib.payload.api.PayloadChannel -import dev.wanderia.testmod.payloads.TestModPayload -import java.util.* -import net.fabricmc.api.ModInitializer -import net.fabricmc.fabric.api.networking.v1.ServerConfigurationConnectionEvents -import net.fabricmc.fabric.api.networking.v1.ServerConfigurationNetworking -import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents -import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking - -object TestMod : ModInitializer { - override fun onInitialize() { - ServerPlayConnectionEvents.JOIN.register { handler, _, _ -> - ServerPlayNetworking.registerReceiver(handler, TestModPayload.payloadId) { payload, _ -> - println(payload.toString()) - } - - if (ServerPlayNetworking.canSend(handler.player, TestModPayload.payloadId)) { - ServerPlayNetworking.send(handler.player, dummyPayload) - } - } - - ServerConfigurationConnectionEvents.CONFIGURE.register { handler, _ -> - ServerConfigurationNetworking.registerReceiver(handler, TestModPayload.payloadId) { - payload, - _ -> - println(payload.toString()) - } - - if (ServerConfigurationNetworking.canSend(handler, TestModPayload.payloadId)) { - ServerConfigurationNetworking.send(handler, dummyPayload) - } - } - } - - public val dummyPayload: TestModPayload = - TestModPayload( - testBoolean = true, - testByte = 0b0, - testChar = 'a', - testDouble = 0.0, - testFloat = 0f, - testInt = 1, - testLong = 1L, - testShort = 1.toShort(), - testString = "test", - testEnum = PayloadChannel.ClientboundPlay, - testCollection = PayloadChannel.entries, - testId = TestModPayload.payloadId.id, - testUUID = UUID.randomUUID(), - ) -} diff --git a/src/testmod/kotlin/TestModClient.kt b/src/testmod/kotlin/TestModClient.kt deleted file mode 100644 index 6eeca23..0000000 --- a/src/testmod/kotlin/TestModClient.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2024 Wanderia - All Rights Reserved - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ -package dev.wanderia.testmod - -import dev.wanderia.testmod.TestMod.dummyPayload -import dev.wanderia.testmod.payloads.TestModPayload -import net.fabricmc.api.ClientModInitializer -import net.fabricmc.fabric.api.client.networking.v1.ClientConfigurationConnectionEvents -import net.fabricmc.fabric.api.client.networking.v1.ClientConfigurationNetworking -import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents -import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking - -object TestModClient : ClientModInitializer { - override fun onInitializeClient() { - ClientConfigurationConnectionEvents.START.register { _, _ -> - ClientConfigurationNetworking.registerReceiver(TestModPayload.payloadId) { payload, _ -> - println(payload.toString()) - } - - if (ClientConfigurationNetworking.canSend(TestModPayload.payloadId)) { - ClientConfigurationNetworking.send(dummyPayload) - } - } - - ClientPlayConnectionEvents.JOIN.register { _, _, _ -> - ClientPlayNetworking.registerReceiver(TestModPayload.payloadId) { payload, _ -> - println(payload.toString()) - } - - if (ClientPlayNetworking.canSend(TestModPayload.payloadId)) { - ClientPlayNetworking.send(dummyPayload) - } - } - } -} diff --git a/src/testmod/kotlin/payloads/TestModPayload.kt b/src/testmod/kotlin/payloads/TestModPayload.kt deleted file mode 100644 index 8a669ed..0000000 --- a/src/testmod/kotlin/payloads/TestModPayload.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2024 Wanderia - All Rights Reserved - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ -package dev.wanderia.testmod.payloads - -import dev.wanderia.netlib.payload.api.PayloadChannel -import dev.wanderia.netlib.payload.api.SerializedPayload -import dev.wanderia.netlib.payload.api.SerializedPayloadConfiguration -import java.util.UUID -import kotlinx.serialization.Contextual -import kotlinx.serialization.ExperimentalSerializationApi -import kotlinx.serialization.Serializable -import net.minecraft.network.RegistryFriendlyByteBuf -import net.minecraft.network.codec.StreamCodec -import net.minecraft.network.protocol.common.custom.CustomPacketPayload -import net.minecraft.resources.ResourceLocation - -@OptIn(ExperimentalSerializationApi::class) -@Serializable -data class TestModPayload( - val testBoolean: Boolean, - val testByte: Byte, - val testChar: Char, - val testDouble: Double, - val testFloat: Float, - val testInt: Int, - val testLong: Long, - val testShort: Short, - val testString: String, - val testEnum: PayloadChannel, - val testCollection: Collection, - @Contextual val testId: ResourceLocation, - @Contextual val testUUID: UUID, -) : SerializedPayload() { - override fun codec(): StreamCodec = payloadCodec - - override fun type(): CustomPacketPayload.Type = payloadId - - companion object Configuration : SerializedPayloadConfiguration { - override val payloadId: CustomPacketPayload.Type = - CustomPacketPayload.Type(ResourceLocation.fromNamespaceAndPath("testmod", "payload")) - override val payloadCodec: StreamCodec = - createCodec() - override val channels: Set = PayloadChannel.entries.toSet() - } -} diff --git a/src/testmod/resources/fabric.mod.json b/src/testmod/resources/fabric.mod.json deleted file mode 100644 index 6004b5b..0000000 --- a/src/testmod/resources/fabric.mod.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "schemaVersion": 1, - "id": "testmod", - "version": "0", - "environment": "*", - "entrypoints": { - "main": [ - { - "adapter": "kotlin", - "value": "dev.wanderia.testmod.TestMod" - } - ], - "client": [ - { - "adapter": "kotlin", - "value": "dev.wanderia.testmod.TestModClient" - } - ], - "wanderia-netlib": [ - { - "adapter": "kotlin", - "value": "dev.wanderia.testmod.NetLibInit" - } - ] - } -} \ No newline at end of file