Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 10 additions & 56 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,40 +1,24 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
kotlin("jvm") version "2.2.20"
id("gg.grounds.base-conventions") version "0.6.0"
// KSP for moshi-kotlin-codegen — generates JsonAdapter classes at
// compile time so the shaded JAR doesn't have to ship kotlin-reflect.
// Reflection-based KotlinJsonAdapterFactory + ShadowJar's `relocate(kotlin)`
// produced corrupted paths inside the .kotlin_builtins resources
// (`gg/grounds/platform/shaded/kotlin/gg.grounds.platform.shaded.kotlin.…_builtins`)
// and crashed Moshi's adapter() at plugin onEnable. Codegen sidesteps the
// whole reflection path.
id("com.google.devtools.ksp") version "2.2.20-2.0.4"
id("com.gradleup.shadow") version "9.4.1"
id("com.diffplug.spotless") version "8.4.0"
id("com.google.devtools.ksp") version "2.3.7"
}

group = "gg.grounds"
apply(plugin = "gg.grounds.paper-conventions")

// release.yml workflow passes the version stripped from the `vX.Y.Z`
// tag via -PversionOverride. Local builds get a SNAPSHOT.
version = (project.findProperty("versionOverride") as? String) ?: "local-SNAPSHOT"

repositories {
mavenCentral()
maven("https://repo.papermc.io/repository/maven-public/")
}
// Tests need Paper on both compile + runtime classpaths because Mockito
// loads the target class to generate the proxy.
configurations { testImplementation { extendsFrom(compileOnly.get()) } }

dependencies {
compileOnly("io.papermc.paper:paper-api:1.21.4-R0.1-SNAPSHOT")
// Tests need Paper on both compile + runtime classpaths because
// Mockito loads the target class to generate the proxy. testCompileOnly
// alone passes compilation but throws ClassNotFoundException when
// mock(Server::class) runs.
testImplementation("io.papermc.paper:paper-api:1.21.4-R0.1-SNAPSHOT")

implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2")
// Compact JSON parser — sufficient for the small whitelist payloads
// we get back from forge. Avoids pulling in jackson / gson which
Expand All @@ -45,34 +29,15 @@ dependencies {

testImplementation("org.junit.jupiter:junit-jupiter:5.11.3")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
testImplementation("org.mockito.kotlin:mockito-kotlin:5.4.0")
testImplementation("org.mockito:mockito-core:5.14.2")
testImplementation("org.mockito.kotlin:mockito-kotlin:6.3.0")
testImplementation("org.mockito:mockito-core:5.23.0")
testImplementation("com.squareup.okhttp3:mockwebserver:4.12.0")
testRuntimeOnly("org.slf4j:slf4j-simple:2.0.16")
}

kotlin { jvmToolchain(21) }

java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}

tasks.withType<JavaCompile>().configureEach { options.release.set(21) }

tasks.withType<KotlinCompile>().configureEach { compilerOptions.jvmTarget.set(JvmTarget.JVM_21) }

tasks.test { useJUnitPlatform() }

// Substitute the version into plugin.yml at build time so the on-server
// Plugins listing matches what's actually deployed.
tasks.processResources {
val versionExpansion = mapOf("VERSION" to project.version.toString())
inputs.properties(versionExpansion)
filesMatching("plugin.yml") { expand(versionExpansion) }
}

tasks.named<ShadowJar>("shadowJar") {
archiveBaseName.set(rootProject.name)
archiveVersion.set(project.version.toString())
archiveClassifier.set("all")
// Relocate the few non-Paper deps so they can't collide with another
// plugin's classpath inside the same JVM.
Expand All @@ -82,14 +47,3 @@ tasks.named<ShadowJar>("shadowJar") {
relocate("okio", "gg.grounds.platform.shaded.okio")
mergeServiceFiles()
}

spotless {
kotlin {
ktfmt("0.55").kotlinlangStyle()
target("src/**/*.kt")
}
kotlinGradle {
ktfmt("0.55").kotlinlangStyle()
target("*.gradle.kts")
}
}
8 changes: 7 additions & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
pluginManagement {
repositories {
mavenCentral()
maven {
url = uri("https://maven.pkg.github.com/groundsgg/*")
credentials {
username = providers.gradleProperty("github.user").get()
password = providers.gradleProperty("github.token").get()
Comment on lines +5 to +7
}
}
gradlePluginPortal()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ data class WhitelistEntry(val mcUuid: String, val mcUsername: String)
/**
* Read-only HTTP client for the forge whitelist endpoint. Uses the JDK built-in HttpClient (already
* on the classpath, no shading required) with a short connect / request timeout — the plugin polls
* on a 30s cadence so a hung forge shouldn't block the Paper main thread.
* on a 30s cadence, so a hung forge shouldn't block the Paper main thread.
*
* Auth header is set per request from the GROUNDS_TOKEN env var, never from a stored field, so
* logging / debugging this client cannot accidentally surface the token.
Expand All @@ -44,7 +44,7 @@ class WhitelistApiClient(

/**
* Fetches the current whitelist. Throws on any non-2xx — caller decides whether to surface or
* swallow (the periodic poller swallows + logs at WARN to keep transient forge hiccups from
* swallow (the periodic poller swallows and logs at WARN to keep transient forge hiccups from
* spamming ERROR).
*/
fun fetch(): List<WhitelistEntry> {
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: GroundsPlatform
version: ${VERSION}
main: gg.grounds.platform.GroundsPlatformPlugin
api-version: "1.21"
api-version: "26.1.2"
description: "Grounds Platform context for Paper servers — project-aware MOTD + whitelist sync"
authors: ["grounds"]
load: STARTUP