Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
eb95cbe
feat: minestom server and plugin api
TheBjoRedCraft Oct 4, 2026
e2451ef
fix(ci): mark vendor/gradlew as executable
TheBjoRedCraft Oct 4, 2026
3a0ad82
🔧 chore: update version to 2.2.1-PR435 and 3.46.1-PR435 in build files
TheBjoRedCraft Oct 4, 2026
84ad347
✨ feat(minestom): add gremlin support for library management and boot…
TheBjoRedCraft Oct 4, 2026
05143e6
✨ feat(minestom): enhance library management with surf modules support
TheBjoRedCraft Oct 4, 2026
d6e7bc7
🔧 chore: update version numbers in build files and add plugin depende…
TheBjoRedCraft Oct 4, 2026
90429a8
🔧 chore: update version to 3.47.1 in gradle.properties
TheBjoRedCraft Oct 4, 2026
592710e
🔧 chore(deps): update minestom dependencies and add snapshot repository
TheBjoRedCraft Oct 13, 2026
d4ae44e
🔧 chore: update version to 3.47.2 in gradle.properties
TheBjoRedCraft Oct 13, 2026
48c9d9c
🔧 chore(build): build the Minestom module against Minestom 26.3
TheBjoRedCraft Oct 13, 2026
8150b5a
Merge branch 'version/26.3' into feat/minestom-server-api
TheBjoRedCraft Oct 13, 2026
c2da9ad
Merge branch 'version/26.3' into feat/minestom-server-api
TheBjoRedCraft Oct 14, 2026
c57e246
Merge remote-tracking branch 'origin/version/26.3' into feat/minestom…
twisti-dev Oct 16, 2026
4ee68f3
✨ feat(mixin): add mixins for entity tracking and NPC display synchro…
twisti-dev Oct 16, 2026
490a239
📝 docs: update comments for clarity in event handling classes
twisti-dev Oct 16, 2026
b933eb6
✨ feat(chat): enhance chat spam threshold functionality
twisti-dev Oct 16, 2026
8ab6429
♻️ refactor(api): replace @ApiStatus.Internal with @InternalSurfApi a…
twisti-dev Oct 16, 2026
975ad49
```
TheBjoRedCraft Oct 16, 2026
e2f2801
```
TheBjoRedCraft Oct 16, 2026
1bba4f9
🐛 fix(minestom): address code review findings across server, chat, co…
twisti-dev Oct 16, 2026
ca83737
🔧 chore(build): downgrade version to 2.4.0 in build.gradle.kts and 3.…
twisti-dev Oct 16, 2026
3ddf953
👷 ci(publish): update CI configuration for submodule initialization a…
twisti-dev Oct 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
14 changes: 14 additions & 0 deletions .github/workflows/api-dump-version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ jobs:
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5

- name: Init submodules
shell: bash
run: git -c 'url.https://github.com/.insteadOf=git@github.com:' submodule update --init --recursive

- name: Apply vendor patches
shell: bash
working-directory: vendor
env:
GIT_AUTHOR_NAME: github-actions
GIT_AUTHOR_EMAIL: actions@slne.dev
GIT_COMMITTER_NAME: github-actions
GIT_COMMITTER_EMAIL: actions@slne.dev
run: ./gradlew applyPatches

- name: Run Kotlin Binary Compatibility Check
id: check_api
run: |
Expand Down
14 changes: 14 additions & 0 deletions .github/workflows/build-pr-jar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ jobs:
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5

- name: Init submodules
shell: bash
run: git -c 'url.https://github.com/.insteadOf=git@github.com:' submodule update --init --recursive

- name: Apply vendor patches
shell: bash
working-directory: vendor
env:
GIT_AUTHOR_NAME: github-actions
GIT_AUTHOR_EMAIL: actions@slne.dev
GIT_COMMITTER_NAME: github-actions
GIT_COMMITTER_EMAIL: actions@slne.dev
run: ./gradlew applyPatches

- name: Build modules with Gradle
run: ./gradlew build shadowJar --parallel --no-scan

Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,10 @@ jobs:
with:
modules: "surf-api-paper-server-*-all.jar;surf-api-velocity-server-*-all.jar;surf-api-standalone-server-*-all.jar"
check-kotlin-abi: true
pre-build-command: |
git -c 'url.https://github.com/.insteadOf=git@github.com:' submodule update --init --recursive
cd vendor
GIT_AUTHOR_NAME=github-actions GIT_AUTHOR_EMAIL=actions@slne.dev \
GIT_COMMITTER_NAME=github-actions GIT_COMMITTER_EMAIL=actions@slne.dev \
./gradlew applyPatches
secrets: inherit
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "vendor/LuckPerms-Upstream"]
path = vendor/LuckPerms-Upstream
url = https://github.com/TropicalShadow/LuckPerms.git
7 changes: 7 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ allprojects {
repositories {
mavenCentral()
maven("https://repo.papermc.io/repository/maven-public/")
maven("https://central.sonatype.com/repository/maven-snapshots/") {
name = "minestom-snapshots"
mavenContent {
snapshotsOnly()
includeGroup("net.minestom")
}
}
maven("https://repo.wyck.dev/snapshots/")
}

Expand Down
1 change: 1 addition & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ dependencies {
implementation(libs.kotlin.serialization)
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
implementation(libs.asm)
implementation(libs.gremlin.gradle.plugin)
}
78 changes: 78 additions & 0 deletions buildSrc/src/main/kotlin/vendor-bundle-convention.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import org.gradle.api.artifacts.component.ModuleComponentIdentifier

/**
* Bundles the vendor builds in `vendor/` into the module's own jar, the way surf-minestom-lobby
* bundles them into its server jar.
*
* The vendor artifacts are built from source and published nowhere, so they cannot appear as
* dependencies of a published module. Declare them in the `bundled` configuration instead: their
* classes, and those of everything they pull in, are copied into the jar, except for the libraries
* a Minestom server already provides.
*/

plugins {
id("core-convention")
}

/**
* Libraries a Minestom server provides itself, which are therefore never bundled.
*/
private val providedGroups = setOf(
"org.slf4j",
"org.jspecify",
"org.jetbrains",
"org.jetbrains.kotlin",
"org.jetbrains.kotlinx",
"org.checkerframework",
"com.google.code.gson",
"com.google.guava",
"com.google.errorprone",
)

/**
* Adventure ships with Minestom, apart from the few extensions spark brings along.
*/
private val providedAdventureModules = Regex("adventure-(api|key|nbt|text-(minimessage|logger-slf4j|serializer-.*))|option|examination-.*")

/**
* Libraries the module declares as regular dependencies instead of bundling them. A bundled ASM
* would end up on the system class path ahead of the ASM the server's library download relocates
* with. The relocation would then run on the bundled version, which cannot read current class
* files.
*/
private val declaredGroups = setOf(
"org.ow2.asm",
)

private fun isProvided(id: ModuleComponentIdentifier): Boolean =
id.group in providedGroups || id.group in declaredGroups ||
(id.group == "net.kyori" && providedAdventureModules.matches(id.module))

val bundled: Configuration = configurations.create("bundled") {
description = "Vendor builds copied into this module's jar instead of being published as dependencies"
isCanBeConsumed = false
isCanBeResolved = true
}

configurations.compileOnly { extendsFrom(bundled) }
configurations.testImplementation { extendsFrom(bundled) }

val bundledFiles = bundled.incoming.artifactView {
componentFilter { id -> id !is ModuleComponentIdentifier || !isProvided(id) }
}.files

tasks.jar {
inputs.files(bundledFiles)

from(bundledFiles.elements.map { files -> files.map { zipTree(it.asFile) } }) {
exclude(
"module-info.class",
"META-INF/versions/*/module-info.class",
"META-INF/MANIFEST.MF",
"META-INF/*.SF",
"META-INF/*.DSA",
"META-INF/*.RSA",
"META-INF/maven/**",
)
}
}
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled
javaVersion=25
mcVersion=26.3
group=dev.slne.surf.api
version=3.47.1
version=3.48.0
relocationPrefix=dev.slne.surf.api.libs
snapshot=false
32 changes: 30 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ commandapiplugin = "12.1.0"
luckperms = "5.5"
luckpermsplugin-bukkit = "v5.5.71-bukkit" # "luckpermsplugin" is written without a separating "-" between "luckperms" and "plugin", because Gradle interprets the version catalog key as a hierarchical alias and would split it into a nested accessor (libs.luckperms.plugin.bukkit), which conflicts with the existing libs.luckperms alias for the API dependency.

# Minestom
minestom-server = "26_3-SNAPSHOT" # experimental 26.3 builds, from the Sonatype snapshot repository
minestom-brigadier = "1.3.10"
minestom-npc = "0.1.3"
luckpermsMinestom = "5.5+26.2-SNAPSHOT" # substituted by the vendor/LuckPerms included build
sparkMinestom = "1.10.181-SNAPSHOT" # substituted by the vendor/spark-minestom included build
terminal-console-appender = "1.3.0"
log4j = "2.26.1"

# Scoreboard Library
scoreboard-library = "2.8.2"

Expand All @@ -37,6 +46,9 @@ mccoroutine = "2.23.1"

# Miscellaneous Libraries
asm = "9.10.1"
sponge-mixin = "0.17.5+mixin.0.8.7"
mixinextras = "0.5.5"
flare = "2.0.1" # the version Minestom uses at runtime
slf4j = "2.0.20"
guava = "33.7.1-jre"
caffeine = "3.3.0"
Expand Down Expand Up @@ -67,14 +79,15 @@ ksp-version = "2.3.12"
reactor-netty = "1.3.7"
bytebuddy = "1.18.14"
wyck = "4.0.0-e5d01de"
gremlin = "0.0.9"

# Testing
junit = "6.1.3"
junit-platform-launcher = "6.1.3"
mockk = "1.14.11"
lincheck = "3.7"
mockbukkit = "4.116.1"
minestom-testing = "2026.09.12-26.2"
minestom-testing = "26_3-SNAPSHOT"

# Plugin versions
maven-repo-auth = "3.0.4"
Expand All @@ -88,7 +101,16 @@ paper-api = { module = "io.papermc.paper:paper-api", version.ref = "paper-api" }
canvas-api = { module = "io.canvasmc.canvas:canvas-api", version.ref = "canvas-api" }

# Minestom
surf-minestom-lobby-api = { module = "dev.slne.minestom.lobby:surf-minestom-lobby-api", version = "+" }
minestom-server = { module = "net.minestom:minestom", version.ref = "minestom-server" }
minestom-brigadier = { module = "com.mojang:brigadier", version.ref = "minestom-brigadier" }
minestom-npc = { module = "codes.bed.minestom:npc", version.ref = "minestom-npc" }
minestom-luckperms = { module = "club.tesseract:luckperms-minestom", version.ref = "luckpermsMinestom" }
minestom-spark = { module = "me.lucko:spark-minestom", version.ref = "sparkMinestom" }
minestom-spark-common = { module = "me.lucko:spark-common", version.ref = "sparkMinestom" }
terminal-console-appender = { module = "net.minecrell:terminalconsoleappender", version.ref = "terminal-console-appender" }
log4j-api = { module = "org.apache.logging.log4j:log4j-api", version.ref = "log4j" }
log4j-core = { module = "org.apache.logging.log4j:log4j-core", version.ref = "log4j" }
log4j-slf4j2-impl = { module = "org.apache.logging.log4j:log4j-slf4j2-impl", version.ref = "log4j" }

# Kotlin
kotlinxCoroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinxCoroutines" }
Expand Down Expand Up @@ -144,6 +166,9 @@ mccoroutine-velocity-core = { module = "dev.slne.forks.mccoroutine:mccoroutine-v

# Miscellaneous Libraries
asm = { module = "org.ow2.asm:asm", version.ref = "asm" }
sponge-mixin = { module = "net.fabricmc:sponge-mixin", version.ref = "sponge-mixin" }
mixinextras = { module = "io.github.llamalad7:mixinextras-common", version.ref = "mixinextras" }
flare-fastutil = { module = "space.vectrix.flare:flare-fastutil", version.ref = "flare" }
slf4j = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" }
guava = { module = "com.google.guava:guava", version.ref = "guava" }
caffeine = { module = "com.github.ben-manes.caffeine:caffeine", version.ref = "caffeine" }
Expand Down Expand Up @@ -174,6 +199,7 @@ glm = { module = "io.github.kotlin-graphics:glm", version.ref = "glm" }
datafixerupper = { module = "com.mojang:datafixerupper", version.ref = "datafixerupper" }
luckperms = { module = "net.luckperms:api", version.ref = "luckperms" }
wyck = { module = "dev.wyck:wyck", version.ref = "wyck" }
gremlin-runtime = { module = "xyz.jpenilla:gremlin-runtime", version.ref = "gremlin" }

auto-service-annotations = { module = "com.google.auto.service:auto-service-annotations", version.ref = "auto-service" }
auto-service = { module = "dev.zacsweers.autoservice:auto-service-ksp", version.ref = "auto-service-ksp" }
Expand All @@ -184,6 +210,7 @@ ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx
reactor-netty-core = { module = "io.projectreactor.netty:reactor-netty-core", version.ref = "reactor-netty" }
reactor-netty-http = { module = "io.projectreactor.netty:reactor-netty-http", version.ref = "reactor-netty" }
bytebuddy = { module = "net.bytebuddy:byte-buddy", version.ref = "bytebuddy" }
bytebuddy-agent = { module = "net.bytebuddy:byte-buddy-agent", version.ref = "bytebuddy" }

# Testing
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" }
Expand All @@ -206,6 +233,7 @@ ksp-gradle-plugin = { module = "com.google.devtools.ksp:com.google.devtools.ksp.
ksp-api = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp-version" }
plugin-yml-paper-gradle-plugin = { module = "de.eldoria.plugin-yml.paper:de.eldoria.plugin-yml.paper.gradle.plugin", version.ref = "plugin-yml-paper" }
run-paper-gradle-plugin = { module = "xyz.jpenilla.run-paper:xyz.jpenilla.run-paper.gradle.plugin", version.ref = "run-paper-gradle-plugin" }
gremlin-gradle-plugin = { module = "xyz.jpenilla.gremlin-gradle:xyz.jpenilla.gremlin-gradle.gradle.plugin", version.ref = "gremlin" }
dokka-gradle-plugin = { module = "org.jetbrains.dokka:org.jetbrains.dokka.gradle.plugin", version.ref = "dokka" }

[plugins]
Expand Down
40 changes: 39 additions & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,49 @@ include("surf-api-shared")
include("surf-api-shared:surf-api-shared-public")
include("surf-api-shared:surf-api-shared-internal")

include("surf-api-minestom")
include(":surf-api-minestom:surf-api-minestom")
include(":surf-api-minestom:surf-api-minestom-server")
include(":surf-api-minestom:surf-api-minestom-server-bootstrap")
include(":surf-api-minestom:surf-api-minestom-server-signed-chat")
include(":surf-api-minestom:surf-api-minestom-server-npc")
include(":surf-api-minestom:surf-api-minestom-server-player-visibility")
include(":surf-api-minestom:surf-api-minestom-server-console")
include(":surf-api-minestom:surf-api-minestom-server-spark")
include(":surf-api-minestom:surf-api-minestom-server-plugins")

includeBuild("vendor/spark-minestom") {
dependencySubstitution {
substitute(module("me.lucko:spark-minestom")).using(project(":"))
}
}

val ci = System.getenv("CI")?.toBoolean() ?: false

// vendor/LuckPerms is generated from the LuckPerms-Upstream submodule and the patches next to it,
// so the LuckPerms feature is only built once it has been created; CI builds require it
val luckPermsDir = file("vendor/LuckPerms")
if (luckPermsDir.resolve("settings.gradle").isFile) {
include(":surf-api-minestom:surf-api-minestom-server-luckperms")

includeBuild(luckPermsDir) {
dependencySubstitution {
substitute(module("club.tesseract:luckperms-minestom")).using(project(":minestom"))
}
}
} else {
val message = """
vendor/LuckPerms is missing, so surf-api-minestom-server-luckperms is not built. Create it with:
git submodule update --init --recursive
cd vendor && ./gradlew applyPatches
""".trimIndent()

if (ci) error(message)
logger.warn(message)
}

if (!ci) {
include(":surf-api-paper:surf-api-paper-plugin-test")
include(":surf-api-minestom:surf-api-minestom-example")
include(":surf-api-minestom:surf-api-minestom-example-plugin")
include("surf-api-generator")
}
23 changes: 20 additions & 3 deletions surf-api-gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ plugins {

group = groupId
version = buildString {
append("2.3.0")
append("2.4.0")
if (snapshot) append("-SNAPSHOT")
}

Expand All @@ -37,7 +37,8 @@ val pluginDependencies = listOf(
libs.shadow.gradle.plugin,
libs.run.paper.gradle.plugin,
libs.plugin.yml.paper.gradle.plugin,
libs.ksp.gradle.plugin
libs.ksp.gradle.plugin,
libs.gremlin.gradle.plugin,
)

dependencies {
Expand Down Expand Up @@ -95,6 +96,12 @@ gradlePlugin {
implementationClass = "dev.slne.surf.api.gradle.platform.minestom.MinestomSurfPlugin"
}

create("minestom-server") {
id = "dev.slne.surf.api.gradle.minestom-server"
implementationClass =
"dev.slne.surf.api.gradle.platform.minestom.server.MinestomServerSurfPlugin"
}

create("minestom-relocations") {
id = "dev.slne.surf.api.gradle.minestom-relocations"
implementationClass =
Expand Down Expand Up @@ -131,7 +138,10 @@ val generateConstants = tasks.register("generateConstants") {
inputs.property("libs.auto.service.annotations", libs.auto.service.annotations.get().toString())
inputs.property("libs.versions.commandapiplugin", libs.versions.commandapiplugin.get())
inputs.property("libs.versions.placeholder.api", libs.versions.placeholder.api.get())
inputs.property("libs.versions.luckpermsplugin.bukkit", libs.versions.luckpermsplugin.bukkit.get())
inputs.property(
"libs.versions.luckpermsplugin.bukkit",
libs.versions.luckpermsplugin.bukkit.get()
)
inputs.property(
"libs.versions.packetevents",
libs.versions.packetevents.plugin.get()
Expand All @@ -150,6 +160,9 @@ val generateConstants = tasks.register("generateConstants") {
inputs.property("libs.versions.mockbukkit", libs.versions.mockbukkit.get())
inputs.property("libs.versions.minestom.testing", libs.versions.minestom.testing.get())
inputs.property("libs.versions.kotlinxCoroutines", libs.versions.kotlinxCoroutines.get())
inputs.property("libs.minestom.server", libs.minestom.server.get().toString())
inputs.property("libs.versions.log4j", libs.versions.log4j.get())
inputs.property("libs.versions.asm", libs.versions.asm.get())
outputs.dir(constantsOutputDir)

doLast {
Expand Down Expand Up @@ -184,6 +197,10 @@ val generateConstants = tasks.register("generateConstants") {
| const val TEST_MINESTOM_TESTING_VERSION = "${libs.versions.minestom.testing.get()}"
| const val TEST_COROUTINES_VERSION = "${libs.versions.kotlinxCoroutines.get()}"
|
| const val MINESTOM = "${libs.minestom.server.get()}"
| const val LOG4J_VERSION = "${libs.versions.log4j.get()}"
| const val ASM_VERSION = "${libs.versions.asm.get()}"
|
| const val SURF_API_FULL_VERSION = "${rootProject.findProperty("version") as String + if (snapshot) "-SNAPSHOT" else ""}"
|}
""".trimMargin()
Expand Down
Loading
Loading