From 14cf430f141314896e0ac57be943040568743287 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Apr 2026 20:09:48 +0000 Subject: [PATCH 01/34] Add V26_1NmsProvider implementation for Minecraft 26.1 Implements the NmsProvider interface with version-specific bridge factories, packet listeners, reflection initialization, and ServiceLoader discovery via @AutoService. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: TheBjoRedCraft <143264463+TheBjoRedCraft@users.noreply.github.com> --- settings.gradle.kts | 3 + .../build.gradle.kts | 8 ++ .../surf/api/paper/nms/common/NmsProvider.kt | 86 +++++++++++++++++++ .../surf/api/paper/nms/common/NmsVersion.kt | 30 +++++++ .../build.gradle.kts | 28 ++++++ .../surf-api-paper-nms-v26-1/build.gradle.kts | 28 ++++++ .../server/nms/v26_1/V26_1NmsProvider.kt | 61 +++++++++++++ 7 files changed, 244 insertions(+) create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/build.gradle.kts create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersion.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/build.gradle.kts create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/build.gradle.kts create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt diff --git a/settings.gradle.kts b/settings.gradle.kts index 5ee117d36..54595079b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -17,6 +17,9 @@ include(":surf-api-core:surf-api-core") include(":surf-api-core:surf-api-core-server") include(":surf-api-paper:surf-api-paper") +include(":surf-api-paper:surf-api-paper-nms:surf-api-paper-nms-common") +include(":surf-api-paper:surf-api-paper-nms:surf-api-paper-nms-v26-1") +include(":surf-api-paper:surf-api-paper-nms:surf-api-paper-nms-v1-21-11") include(":surf-api-paper:surf-api-paper-server") include(":surf-api-velocity:surf-api-velocity") diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/build.gradle.kts b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/build.gradle.kts new file mode 100644 index 000000000..2f07109c5 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/build.gradle.kts @@ -0,0 +1,8 @@ +plugins { + `core-convention` +} + +dependencies { + api(projects.surfApiPaper.surfApiPaper) + compileOnly(libs.paper.api) +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt new file mode 100644 index 000000000..3acd6f38c --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt @@ -0,0 +1,86 @@ +package dev.slne.surf.api.paper.nms.common + +import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge +import dev.slne.surf.api.paper.nms.bridges.* +import dev.slne.surf.api.paper.nms.bridges.packets.SurfPaperNmsPacketBridges +import dev.slne.surf.api.paper.nms.bridges.packets.block.SurfPaperNmsBlockPackets +import dev.slne.surf.api.paper.nms.bridges.packets.entity.SurfPaperNmsSpawnPackets +import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerChatPackets +import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerPackets +import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToastPackets +import dev.slne.surf.api.paper.packet.listener.listener.PacketListener +import dev.slne.surf.api.paper.region.TickThreadGuard + +/** + * Main interface for version-specific NMS operations. + * + * Each supported Minecraft version provides an implementation of this interface + * that creates the appropriate NMS bridge implementations and packet listeners. + * + * Implementations are discovered at runtime using [java.util.ServiceLoader]. + */ +interface NmsProvider { + /** + * The NMS version this provider supports. + */ + val version: NmsVersion + + // ==================== Bridge Factories ==================== // + + fun createNmsBridge(): SurfPaperNmsBridge + fun createCommonBridge(): SurfPaperNmsCommonBridge + fun createEntityBridge(): SurfPaperNmsEntityBridge + fun createItemBridge(): SurfPaperNmsItemBridge + fun createNbtBridge(): SurfPaperNmsNbtBridge + fun createGlowingBridge(): SurfPaperNmsGlowingBridge + fun createStatsBridge(): SurfPaperNmsStatsBridge + fun createLootTableBridge(): SurfPaperNmsLootTableBridge + fun createCommandArgumentTypesBridge(): SurfPaperNmsCommandArgumentTypesBridge + fun createPacketBridges(): SurfPaperNmsPacketBridges + fun createBlockPackets(): SurfPaperNmsBlockPackets + fun createSpawnPackets(): SurfPaperNmsSpawnPackets + fun createPlayerPackets(): SurfPaperNmsPlayerPackets + fun createPlayerChatPackets(): SurfPaperNmsPlayerChatPackets + fun createPlayerToastPackets(): SurfPaperNmsPlayerToastPackets + fun createTickThreadGuard(): TickThreadGuard + + // ==================== Packet Listeners ==================== // + + /** + * Creates version-specific packet listeners (e.g. lore handler, glowing handler). + * + * @return list of packet listeners to be registered with the packet listener API + */ + fun createPacketListeners(): List + + /** + * Initializes version-specific resources. Called during plugin enable. + */ + fun initialize() + + /** + * Cleans up version-specific resources. Called during plugin disable. + */ + fun shutdown() + + companion object { + /** + * Loads the [NmsProvider] for the currently running Minecraft version. + * + * @throws IllegalStateException if no provider is found for the current version + */ + val current: NmsProvider by lazy { + val version = NmsVersion.current + val providers = java.util.ServiceLoader.load( + NmsProvider::class.java, + NmsProvider::class.java.classLoader + ) + + providers.firstOrNull { it.version == version } + ?: throw IllegalStateException( + "No NMS provider found for version $version. " + + "Available providers: ${providers.map { it.version }.joinToString()}" + ) + } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersion.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersion.kt new file mode 100644 index 000000000..b70f33ed1 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersion.kt @@ -0,0 +1,30 @@ +package dev.slne.surf.api.paper.nms.common + +import org.bukkit.Bukkit + +/** + * Represents the supported Minecraft NMS versions. + * + * @property versionPrefix The version prefix used to match `Bukkit.getMinecraftVersion()`. + */ +enum class NmsVersion(val versionPrefix: String) { + V1_21_11("1.21"), + V26_1("26."); + + companion object { + /** + * The NMS version of the currently running Minecraft server. + * + * Detected at runtime from `Bukkit.getMinecraftVersion()`. + * + * @throws IllegalStateException if the server version is not supported + */ + val current: NmsVersion by lazy { + val mcVersion = Bukkit.getMinecraftVersion() + entries.firstOrNull { mcVersion.startsWith(it.versionPrefix) } + ?: throw IllegalStateException( + "Unsupported Minecraft version: $mcVersion. Supported versions: ${entries.joinToString { "${it.name} (${it.versionPrefix}*)" }}" + ) + } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/build.gradle.kts b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/build.gradle.kts new file mode 100644 index 000000000..dc7ec4de8 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/build.gradle.kts @@ -0,0 +1,28 @@ +plugins { + `core-convention` + id("io.papermc.paperweight.userdev") apply true +} + +kotlin { + compilerOptions { + optIn.add("dev.slne.surf.api.paper.visualizer.visualizer.ExperimentalVisualizerApi") + } +} + +dependencies { + api(projects.surfApiPaper.surfApiPaperNms.surfApiPaperNmsCommon) + api(projects.surfApiCore.surfApiCoreServer) + + paperweight.paperDevBundle(libs.canvas.api.get().version) + + compileOnly(libs.placeholder.api) + compileOnly(libs.reflection.remapper) + compileOnly(libs.mccoroutine.folia.api) + compileOnly(libs.scoreboard.library.api) + + implementation(libs.bytebuddy) +} + +configurations.all { + exclude(group = "org.spigotmc", module = "spigot-api") +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/build.gradle.kts b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/build.gradle.kts new file mode 100644 index 000000000..7d1546943 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/build.gradle.kts @@ -0,0 +1,28 @@ +plugins { + `core-convention` + id("io.papermc.paperweight.userdev") apply true +} + +kotlin { + compilerOptions { + optIn.add("dev.slne.surf.api.paper.visualizer.visualizer.ExperimentalVisualizerApi") + } +} + +dependencies { + api(projects.surfApiPaper.surfApiPaperNms.surfApiPaperNmsCommon) + api(projects.surfApiCore.surfApiCoreServer) + + paperweight.paperDevBundle(libs.paper.api.get().version) + + compileOnly(libs.placeholder.api) + compileOnly(libs.reflection.remapper) + compileOnly(libs.mccoroutine.folia.api) + compileOnly(libs.scoreboard.library.api) + + implementation(libs.bytebuddy) +} + +configurations.all { + exclude(group = "org.spigotmc", module = "spigot-api") +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt new file mode 100644 index 000000000..cee1b46e7 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt @@ -0,0 +1,61 @@ +package dev.slne.surf.api.paper.server.nms.v26_1 + +import com.google.auto.service.AutoService +import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge +import dev.slne.surf.api.paper.nms.bridges.* +import dev.slne.surf.api.paper.nms.bridges.packets.SurfPaperNmsPacketBridges +import dev.slne.surf.api.paper.nms.bridges.packets.block.SurfPaperNmsBlockPackets +import dev.slne.surf.api.paper.nms.bridges.packets.entity.SurfPaperNmsSpawnPackets +import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerChatPackets +import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerPackets +import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToastPackets +import dev.slne.surf.api.paper.nms.common.NmsProvider +import dev.slne.surf.api.paper.nms.common.NmsVersion +import dev.slne.surf.api.paper.packet.listener.listener.PacketListener +import dev.slne.surf.api.paper.region.TickThreadGuard +import dev.slne.surf.api.paper.server.nms.v26_1.bridges.* +import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.V26_1SurfPaperNmsPacketBridgesImpl +import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.block.V26_1SurfPaperNmsBlockPacketsImpl +import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.entity.V26_1SurfPaperNmsSpawnPacketsImpl +import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.player.V26_1SurfPaperNmsPlayerChatPacketsImpl +import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.player.V26_1SurfPaperNmsPlayerPacketsImpl +import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.player.V26_1SurfPaperNmsPlayerToastPacketsImpl +import dev.slne.surf.api.paper.server.nms.v26_1.packet.listener.V26_1GlowingPacketListener +import dev.slne.surf.api.paper.server.nms.v26_1.packet.lore.V26_1PacketLoreListener +import dev.slne.surf.api.paper.server.nms.v26_1.reflection.V26_1Reflection +import dev.slne.surf.api.paper.server.nms.v26_1.region.V26_1TickThreadGuard + +@AutoService(NmsProvider::class) +class V26_1NmsProvider : NmsProvider { + override val version: NmsVersion = NmsVersion.V26_1 + + override fun createNmsBridge(): SurfPaperNmsBridge = V26_1SurfPaperNmsBridgeImpl() + override fun createCommonBridge(): SurfPaperNmsCommonBridge = V26_1SurfPaperNmsCommonBridgeImpl() + override fun createEntityBridge(): SurfPaperNmsEntityBridge = V26_1SurfPaperNmsEntityBridgeImpl() + override fun createItemBridge(): SurfPaperNmsItemBridge = V26_1SurfPaperNmsItemBridgeImpl() + override fun createNbtBridge(): SurfPaperNmsNbtBridge = V26_1SurfPaperNmsNbtBridgeImpl() + override fun createGlowingBridge(): SurfPaperNmsGlowingBridge = V26_1SurfPaperNmsGlowingBridgeImpl() + override fun createStatsBridge(): SurfPaperNmsStatsBridge = V26_1SurfPaperNmsStatsBridgeImpl() + override fun createLootTableBridge(): SurfPaperNmsLootTableBridge = V26_1SurfPaperNmsLootTableBridgeImpl() + override fun createCommandArgumentTypesBridge(): SurfPaperNmsCommandArgumentTypesBridge = V26_1SurfPaperNmsCommandArgumentTypesBridgeImpl() + override fun createPacketBridges(): SurfPaperNmsPacketBridges = V26_1SurfPaperNmsPacketBridgesImpl() + override fun createBlockPackets(): SurfPaperNmsBlockPackets = V26_1SurfPaperNmsBlockPacketsImpl() + override fun createSpawnPackets(): SurfPaperNmsSpawnPackets = V26_1SurfPaperNmsSpawnPacketsImpl() + override fun createPlayerPackets(): SurfPaperNmsPlayerPackets = V26_1SurfPaperNmsPlayerPacketsImpl() + override fun createPlayerChatPackets(): SurfPaperNmsPlayerChatPackets = V26_1SurfPaperNmsPlayerChatPacketsImpl() + override fun createPlayerToastPackets(): SurfPaperNmsPlayerToastPackets = V26_1SurfPaperNmsPlayerToastPacketsImpl() + override fun createTickThreadGuard(): TickThreadGuard = V26_1TickThreadGuard() + + override fun createPacketListeners(): List = listOf( + V26_1PacketLoreListener, + V26_1GlowingPacketListener, + ) + + override fun initialize() { + V26_1Reflection.initialize() + } + + override fun shutdown() { + // No cleanup needed + } +} From 66a034d085485488757b7d18276ee1a14e103270 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Apr 2026 20:20:17 +0000 Subject: [PATCH 02/34] Add V26_1 NMS implementation files for multi-version architecture Create all 39 V26_1 versioned NMS implementation files adapted from the paper-server source files: - Extensions: nms-extensions.kt, AdventureNBT.kt (package change only) - Bridge implementations: 9 bridge classes with V26_1 prefix - Packet operations & bridges: PacketOperationImpl, PacketBridgesImpl, block/entity/player packet implementations - Packet listener implementations: NmsPacketImpl, PacketRegistry, clientbound/serverbound packet wrappers - Glowing system: GlowingPacketListener, TeamData, BlockGlowingData - Packet lore: PacketLoreListener - Reflection: Reflection object with initialize() method, 5 proxy interfaces - Region: TickThreadGuard All files follow the V26_1 naming convention: - Package: dev.slne.surf.api.paper.server.nms.v26_1.* - Class names prefixed with V26_1 - @AutoService annotations removed (registered via NmsProvider) - checkInstantiationByServiceLoader() calls removed - Internal cross-references updated to V26_1 prefixed names Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: TheBjoRedCraft <143264463+TheBjoRedCraft@users.noreply.github.com> --- .../bridges/V26_1SurfPaperNmsBridgeImpl.kt | 128 ++++++ ...fPaperNmsCommandArgumentTypesBridgeImpl.kt | 107 +++++ .../V26_1SurfPaperNmsCommonBridgeImpl.kt | 90 ++++ .../V26_1SurfPaperNmsEntityBridgeImpl.kt | 53 +++ .../V26_1SurfPaperNmsGlowingBridgeImpl.kt | 60 +++ .../V26_1SurfPaperNmsItemBridgeImpl.kt | 24 ++ .../V26_1SurfPaperNmsLootTableBridgeImpl.kt | 55 +++ .../bridges/V26_1SurfPaperNmsNbtBridgeImpl.kt | 63 +++ .../V26_1SurfPaperNmsStatsBridgeImpl.kt | 21 + .../packets/V26_1PacketOperationImpl.kt | 115 ++++++ .../V26_1SurfPaperNmsPacketBridgesImpl.kt | 12 + .../V26_1SurfPaperNmsBlockPacketsImpl.kt | 31 ++ .../V26_1SurfPaperNmsSpawnPacketsImpl.kt | 207 ++++++++++ .../V26_1SurfPaperNmsPlayerChatPacketsImpl.kt | 64 +++ .../V26_1SurfPaperNmsPlayerPacketsImpl.kt | 54 +++ ...V26_1SurfPaperNmsPlayerToastPacketsImpl.kt | 60 +++ .../nms/v26_1/extensions/AdventureNBT.kt | 96 +++++ .../nms/v26_1/extensions/nms-extensions.kt | 150 +++++++ .../server/nms/v26_1/glow/V26_1TeamData.kt | 40 ++ .../v26_1/glow/block/V26_1BlockGlowingData.kt | 81 ++++ .../listener/packets/V26_1NmsPacketImpl.kt | 24 ++ .../listener/packets/V26_1PacketRegistry.kt | 78 ++++ .../V26_1ClientboundDisconnectPacketImpl.kt | 14 + .../V26_1ClientboundSystemChatPacketImpl.kt | 25 ++ .../V26_1NmsClientboundPacketImpl.kt | 12 + .../V26_1CommandSuggestionPacketImpl.kt | 13 + .../V26_1NmsServerboundPacketImpl.kt | 10 + .../serverbound/V26_1RenameItemPacketImpl.kt | 11 + ...V26_1ServerboundCustomPayloadPacketImpl.kt | 42 ++ .../serverbound/V26_1SignUpdatePacketImpl.kt | 19 + .../listener/V26_1GlowingPacketListener.kt | 100 +++++ .../packet/lore/V26_1PacketLoreListener.kt | 388 ++++++++++++++++++ .../nms/v26_1/reflection/V26_1EntityProxy.kt | 23 ++ .../nms/v26_1/reflection/V26_1Reflection.kt | 37 ++ .../V26_1ServerConnectionListenerProxy.kt | 12 + .../V26_1ServerStatsCounterProxy.kt | 20 + .../V26_1VanillaArgumentProviderImplProxy.kt | 15 + .../V26_1VanillaArgumentProviderProxy.kt | 14 + .../nms/v26_1/region/V26_1TickThreadGuard.kt | 65 +++ 39 files changed, 2433 insertions(+) create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsBridgeImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsCommandArgumentTypesBridgeImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsCommonBridgeImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsEntityBridgeImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsGlowingBridgeImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsItemBridgeImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsLootTableBridgeImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsNbtBridgeImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsStatsBridgeImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/V26_1PacketOperationImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/V26_1SurfPaperNmsPacketBridgesImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/block/V26_1SurfPaperNmsBlockPacketsImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/entity/V26_1SurfPaperNmsSpawnPacketsImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerChatPacketsImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerPacketsImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerToastPacketsImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/extensions/AdventureNBT.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/extensions/nms-extensions.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1TeamData.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/V26_1BlockGlowingData.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/V26_1NmsPacketImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/V26_1PacketRegistry.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1ClientboundDisconnectPacketImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1ClientboundSystemChatPacketImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1NmsClientboundPacketImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1CommandSuggestionPacketImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1NmsServerboundPacketImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1RenameItemPacketImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1ServerboundCustomPayloadPacketImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1SignUpdatePacketImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1GlowingPacketListener.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/lore/V26_1PacketLoreListener.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1EntityProxy.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1Reflection.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ServerConnectionListenerProxy.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ServerStatsCounterProxy.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1VanillaArgumentProviderImplProxy.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1VanillaArgumentProviderProxy.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/region/V26_1TickThreadGuard.kt diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsBridgeImpl.kt new file mode 100644 index 000000000..7c6d1ef4a --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsBridgeImpl.kt @@ -0,0 +1,128 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.bridges + +import com.google.common.flogger.StackSize +import dev.slne.surf.api.core.util.logger +import dev.slne.surf.api.paper.api.nms.listener.NmsClientboundPacketListener +import dev.slne.surf.api.paper.api.nms.listener.NmsServerboundPacketListener +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge +import dev.slne.surf.api.paper.nms.listener.packets.clientbound.NmsClientboundPacket +import dev.slne.surf.api.paper.nms.listener.packets.serverbound.NmsServerboundPacket +import dev.slne.surf.api.paper.packet.listener.listener.PacketListenerResult +import dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.V26_1NmsPacketImpl +import org.bukkit.entity.Player +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.CopyOnWriteArraySet + +@NmsUseWithCaution +class V26_1SurfPaperNmsBridgeImpl : SurfPaperNmsBridge { + private val log = logger() + + private val serverboundPacketListeners = + ConcurrentHashMap, CopyOnWriteArraySet>>() + private val clientboundPacketListeners = + ConcurrentHashMap, CopyOnWriteArraySet>>() + + override fun registerServerboundPacketListener(listener: NmsServerboundPacketListener<*>) { + val packetClass = listener.packetClass + val added = + serverboundPacketListeners.computeIfAbsent(packetClass) { CopyOnWriteArraySet() } + .add(listener) + + if (!added) { + log.atWarning() + .withStackTrace(StackSize.MEDIUM) + .log("Serverbound packet listener $listener is already registered") + } + } + + override fun unregisterServerboundPacketListener(listener: NmsServerboundPacketListener<*>) { + val removed = serverboundPacketListeners[listener.packetClass]?.remove(listener) == true + + if (!removed) { + log.atWarning() + .withStackTrace(StackSize.MEDIUM) + .log("Serverbound packet listener $listener is not registered") + } + } + + override fun registerClientboundPacketListener(listener: NmsClientboundPacketListener<*>) { + val packetClass = listener.packetClass + val added = + clientboundPacketListeners.computeIfAbsent(packetClass) { CopyOnWriteArraySet() } + .add(listener) + + if (!added) { + log.atWarning() + .withStackTrace(StackSize.MEDIUM) + .log("Clientbound packet listener $listener is already registered") + } + } + + override fun unregisterClientboundPacketListener(listener: NmsClientboundPacketListener<*>) { + val removed = clientboundPacketListeners[listener.packetClass]?.remove(listener) == true + + if (!removed) { + log.atWarning() + .withStackTrace(StackSize.MEDIUM) + .log("Clientbound packet listener $listener is not registered") + } + } + + @Suppress("UNCHECKED_CAST") + fun handleServerboundPacket( + packet: Packet, + player: Player?, + ): Packet? { + val clazz = packet.packetClass + val listener = serverboundPacketListeners[clazz] ?: return packet + + var cancel = false + for (listener in listener) { + listener as NmsServerboundPacketListener + val result = try { + listener.handleEarlyServerboundPacket(packet, player) + } catch (e: Throwable) { + log.atSevere() + .withCause(e) + .log("Failed to handle serverbound packet $clazz for listener $listener") + PacketListenerResult.CONTINUE + } + + if (result == PacketListenerResult.CANCEL) { + cancel = true + } + } + + return if (cancel) null else packet + } + + @Suppress("UNCHECKED_CAST") + fun handleClientboundPacket( + packet: Packet, + player: Player?, + ): Packet? { + val listeners = clientboundPacketListeners[packet.packetClass] ?: return packet + + if (listeners.isEmpty()) return packet + + var cancel = false + for (listener in listeners) { + listener as NmsClientboundPacketListener + val result = try { + listener.handleEarlyClientboundPacket(packet, player) + } catch (e: Throwable) { + log.atSevere() + .withCause(e) + .log("Failed to handle clientbound packet ${packet.packetClass} for listener $listener") + PacketListenerResult.CONTINUE + } + + if (result == PacketListenerResult.CANCEL) { + cancel = true + } + } + + return if (cancel) null else packet + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsCommandArgumentTypesBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsCommandArgumentTypesBridgeImpl.kt new file mode 100644 index 000000000..8ae2c5c8d --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsCommandArgumentTypesBridgeImpl.kt @@ -0,0 +1,107 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.bridges + +import com.mojang.brigadier.arguments.ArgumentType +import com.mojang.brigadier.context.CommandContext +import com.mojang.brigadier.exceptions.CommandSyntaxException +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsCommandArgumentTypesBridge +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.AdventureNBT +import dev.slne.surf.api.paper.server.nms.v26_1.reflection.V26_1Reflection +import net.bytebuddy.ByteBuddy +import net.bytebuddy.dynamic.loading.ClassLoadingStrategy +import net.bytebuddy.dynamic.scaffold.TypeValidation +import net.bytebuddy.implementation.InvocationHandlerAdapter +import net.bytebuddy.implementation.bind.annotation.RuntimeType +import net.bytebuddy.matcher.ElementMatchers +import net.kyori.adventure.nbt.CompoundBinaryTag +import net.minecraft.commands.arguments.CompoundTagArgument +import java.lang.reflect.InvocationHandler +import java.util.concurrent.ConcurrentHashMap + +@NmsUseWithCaution +class V26_1SurfPaperNmsCommandArgumentTypesBridgeImpl : SurfPaperNmsCommandArgumentTypesBridge { + + override fun compoundTag(): ArgumentType<*> { + return CompoundTagArgument.compoundTag() + } + + override fun getCompoundTag(ctx: CommandContext<*>, key: String): CompoundBinaryTag { + val nms = CompoundTagArgument.getCompoundTag(ctx, key) + return AdventureNBT.fromNms(nms) + } + + @Suppress("UNCHECKED_CAST") + private fun wrap( + base: ArgumentType, + converter: OpenedResultConverter + ): ArgumentType { + val wrappedConverter = OpenedResultConverterImpl.of(converter) + val wrapped = V26_1Reflection.VANILLA_ARGUMENT_PROVIDER_IMPL_PROXY.wrap( + V26_1Reflection.VANILLA_ARGUMENT_PROVIDER_PROXY.provider(), + base, + wrappedConverter + ) as ArgumentType + + return wrapped + } + + + fun interface OpenedResultConverter { + @Throws(CommandSyntaxException::class) + fun convert(type: T): R + } + + object OpenedResultConverterImpl { + private val converterCache = ConcurrentHashMap() + + @Suppress("UNCHECKED_CAST") + fun of(converter: OpenedResultConverter): Any { + val cacheKey = "${converter.javaClass.name}_${System.identityHashCode(converter)}" + + return converterCache.computeIfAbsent(cacheKey) { + createConverter(converter) + } + } + + @Suppress("UNCHECKED_CAST") + private fun createConverter(converter: OpenedResultConverter): Any { + val resultConverterInterface = Class.forName( + "io.papermc.paper.command.brigadier.argument.VanillaArgumentProviderImpl\$ResultConverter" + ) + + val handler = InvocationHandler { _, method, args -> + when (method.name) { + "convert" -> converter.convert(args[0] as B) + else -> throw UnsupportedOperationException("Unknown method: ${method.name}") + } + } + + val dynamicType = ByteBuddy() + .with(TypeValidation.DISABLED) + .subclass(Any::class.java) + .implement(resultConverterInterface) + .name("io.papermc.paper.command.brigadier.argument.GeneratedResultConverter\$${System.nanoTime()}") + .method(ElementMatchers.any()) + .intercept(InvocationHandlerAdapter.of(handler)) + .make() + + val loadedClass = dynamicType.load( + resultConverterInterface.classLoader, + ClassLoadingStrategy.Default.INJECTION + ).loaded + + return loadedClass.getDeclaredConstructor().newInstance() + } + + + class InterceptorHolder( + private val converter: OpenedResultConverter + ) { + @RuntimeType + @Throws(Exception::class) + fun convert(@RuntimeType input: B): C { + return converter.convert(input) + } + } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsCommonBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsCommonBridgeImpl.kt new file mode 100644 index 000000000..859176ecb --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsCommonBridgeImpl.kt @@ -0,0 +1,90 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.bridges + +import dev.slne.surf.api.paper.dialog.noticeDialogWithBuilder +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsCommonBridge +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toNms +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toNmsBlock +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toNmsItem +import dev.slne.surf.api.paper.server.nms.v26_1.reflection.V26_1Reflection +import io.papermc.paper.configuration.GlobalConfiguration +import net.kyori.adventure.text.Component +import net.minecraft.network.protocol.common.ClientboundClearDialogPacket +import net.minecraft.server.MinecraftServer +import net.minecraft.world.level.block.Block +import net.minecraft.world.level.block.ComposterBlock +import org.bukkit.Bukkit +import org.bukkit.Material +import org.bukkit.block.data.BlockData +import org.bukkit.entity.Player +import java.net.InetSocketAddress + +@NmsUseWithCaution +class V26_1SurfPaperNmsCommonBridgeImpl : SurfPaperNmsCommonBridge { + + @Suppress("DEPRECATION") + override fun nextEntityId(): Int { + return Bukkit.getUnsafe().nextEntityId() + } + + override fun getStateId(material: Material): Int { + return Block.getId(material.toNmsBlock().defaultBlockState()) + } + + override fun getStateId(blockData: BlockData): Int { + return Block.getId(blockData.toNms()) + } + + override fun generateNextInventoryId(player: Player): Int { + return player.toNms().nextContainerCounter() + } + + override fun addCompostable(material: Material, levelIncreaseChance: Float) { + require(material.isItem) { "material must be an item" } + + ComposterBlock.COMPOSTABLES.put(material.toNmsItem(), levelIncreaseChance) + } + + override fun removeCompostable(material: Material) { + require(material.isItem) { "material must be an item" } + ComposterBlock.COMPOSTABLES.removeFloat(material.toNmsItem()) + } + + override fun setVelocityEnabled(enabled: Boolean) { + GlobalConfiguration.get().proxies.velocity.enabled = enabled + } + + override fun isVelocityEnabled(): Boolean { + return GlobalConfiguration.get().proxies.velocity.enabled + } + + override fun setVelocitySecret(secret: String) { + GlobalConfiguration.get().proxies.velocity.secret = secret + } + + override fun getVelocitySecret(): String { + return GlobalConfiguration.get().proxies.velocity.secret + } + + override fun setOnlineMode(enabled: Boolean) { + MinecraftServer.getServer().setUsesAuthentication(enabled) + } + + override fun clearDialogs(player: Player, showEmptyDialogBefore: Boolean) { + if (showEmptyDialogBefore) { + player.showDialog(noticeDialogWithBuilder(Component.empty()) {}) + } + + player.toNms().connection.send(ClientboundClearDialogPacket.INSTANCE) + } + + override fun getServerIp(): InetSocketAddress { + val channels = + V26_1Reflection.SERVER_CONNECTION_LISTENER_PROXY.getChannels(MinecraftServer.getServer().connection) + val channel = + channels.firstOrNull() ?: error("No channels found in server connection listener proxy") + + return channel.channel().localAddress() as? InetSocketAddress + ?: error("Local address is not an instance of InetSocketAddress") + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsEntityBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsEntityBridgeImpl.kt new file mode 100644 index 000000000..9fd00125b --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsEntityBridgeImpl.kt @@ -0,0 +1,53 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.bridges + +import ca.spottedleaf.moonrise.common.util.TickThread +import com.mojang.brigadier.exceptions.CommandSyntaxException +import dev.jorel.commandapi.exceptions.WrapperCommandSyntaxException +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsEntityBridge +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.AdventureNBT +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toNms +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toNmsHolder +import dev.slne.surf.api.paper.util.chunkX +import dev.slne.surf.api.paper.util.chunkZ +import io.papermc.paper.math.FinePosition +import net.kyori.adventure.nbt.CompoundBinaryTag +import net.minecraft.server.MinecraftServer +import net.minecraft.server.commands.SummonCommand +import org.bukkit.World +import org.bukkit.entity.EntityType + +@NmsUseWithCaution +class V26_1SurfPaperNmsEntityBridgeImpl : SurfPaperNmsEntityBridge { + + @Suppress("UnstableApiUsage") + override fun createEntityByNbt( + world: World, + type: EntityType, + pos: FinePosition, + tag: CompoundBinaryTag + ) { + val worldNMS = world.toNms() + TickThread.ensureTickThread( + worldNMS, + pos.chunkX, + pos.chunkZ, + "Cannot create entity asynchronously" + ) + + val source = MinecraftServer.getServer().createCommandSourceStack() + .withLevel(worldNMS) + + try { + SummonCommand.createEntity( + source, + type.toNmsHolder(), + pos.toNms(), + AdventureNBT.toNms(tag), + false + ) + } catch (e: CommandSyntaxException) { + throw WrapperCommandSyntaxException(e) + } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsGlowingBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsGlowingBridgeImpl.kt new file mode 100644 index 000000000..1c081816e --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsGlowingBridgeImpl.kt @@ -0,0 +1,60 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.bridges + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsGlowingBridge +import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation +import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.V26_1PacketOperationImpl +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toNms +import dev.slne.surf.api.paper.server.nms.v26_1.glow.V26_1TeamData +import dev.slne.surf.api.paper.server.nms.v26_1.packet.listener.V26_1GlowingPacketListener +import dev.slne.surf.api.paper.server.nms.v26_1.reflection.V26_1Reflection +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket +import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket +import net.minecraft.network.syncher.SynchedEntityData.DataValue +import org.bukkit.entity.Entity + +@NmsUseWithCaution +class V26_1SurfPaperNmsGlowingBridgeImpl : SurfPaperNmsGlowingBridge { + fun createTeam(data: V26_1TeamData): PacketOperation = + V26_1PacketOperationImpl.simple { + ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(data.team, true) + } + + fun addEntityToTeam(data: V26_1TeamData, entry: String): PacketOperation = + V26_1PacketOperationImpl.simple { + ClientboundSetPlayerTeamPacket.createPlayerPacket( + data.team, + entry, + ClientboundSetPlayerTeamPacket.Action.ADD + ) + } + + fun removeEntityFromTeam(data: V26_1TeamData, entry: String): PacketOperation = + V26_1PacketOperationImpl.simple { + ClientboundSetPlayerTeamPacket.createPlayerPacket( + data.team, + entry, + ClientboundSetPlayerTeamPacket.Action.REMOVE + ) + } + + fun setEntityFlags(entityId: Int, flags: Byte, ignorePacket: Boolean = false): PacketOperation = + V26_1PacketOperationImpl.simple { + val dataAccessor = V26_1Reflection.ENTITY_PROXY.getDataFlagsSharedId() + val data = DataValue(dataAccessor.id(), dataAccessor.serializer, flags) + ClientboundSetEntityDataPacket(entityId, listOf(data)).also { + if (ignorePacket) { + V26_1GlowingPacketListener.ignorePacket(it) + } + } + } + + override fun getCurrentFlags(entity: Entity): Byte { + val dataAccessor = V26_1Reflection.ENTITY_PROXY.getDataFlagsSharedId() + return entity.toNms().entityData.get(dataAccessor) + } + + companion object { + val INSTANCE get() = SurfPaperNmsGlowingBridge.INSTANCE as V26_1SurfPaperNmsGlowingBridgeImpl + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsItemBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsItemBridgeImpl.kt new file mode 100644 index 000000000..5b75ad965 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsItemBridgeImpl.kt @@ -0,0 +1,24 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.bridges + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsItemBridge +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.nms +import net.minecraft.core.component.DataComponentMap +import net.minecraft.core.component.DataComponents +import org.bukkit.inventory.ItemType + +@NmsUseWithCaution +class V26_1SurfPaperNmsItemBridgeImpl : SurfPaperNmsItemBridge { + + override fun setDefaultMaxStackSize(item: ItemType, maxStackSize: Int) { + require(maxStackSize in 1..100) { "Max stack size must be between 1 and 100" } + + val nmsItem = item.nms + val updatedComponents = DataComponentMap.builder() + .addAll(nmsItem.components()) + .set(DataComponents.MAX_STACK_SIZE, maxStackSize) + .build() + + nmsItem.builtInRegistryHolder().bindComponents(updatedComponents) + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsLootTableBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsLootTableBridgeImpl.kt new file mode 100644 index 000000000..ce78b3740 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsLootTableBridgeImpl.kt @@ -0,0 +1,55 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.bridges + +import dev.slne.surf.api.core.util.emptyObjectList +import dev.slne.surf.api.core.util.mutableObjectListOf +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsLootTableBridge +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toBukkit +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toNms +import net.minecraft.server.MinecraftServer +import net.minecraft.server.level.ServerLevel +import net.minecraft.world.level.storage.loot.LootParams +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets +import net.minecraft.world.level.storage.loot.parameters.LootContextParams +import org.bukkit.damage.DamageSource +import org.bukkit.entity.EntityType +import org.bukkit.entity.LivingEntity +import org.bukkit.inventory.ItemStack +import kotlin.jvm.optionals.getOrNull + +@NmsUseWithCaution +class V26_1SurfPaperNmsLootTableBridgeImpl : SurfPaperNmsLootTableBridge { + override fun getDifferentLootTable( + entity: LivingEntity, + damageSource: DamageSource, + replacement: EntityType, + causedByPlayer: Boolean, + ): Collection { + val lootTableKey = + replacement.toNms().defaultLootTable.getOrNull() ?: return emptyObjectList() + val lootTable = + MinecraftServer.getServer().reloadableRegistries().getLootTable(lootTableKey) + val nmsEntity = entity.toNms() + val nmsDamageSource = damageSource.toNms() + + val lootParamsBuilder = LootParams.Builder(nmsEntity.level() as ServerLevel) + .withParameter(LootContextParams.THIS_ENTITY, nmsEntity) + .withParameter(LootContextParams.ORIGIN, nmsEntity.position()) + .withParameter(LootContextParams.DAMAGE_SOURCE, nmsDamageSource) + .withOptionalParameter(LootContextParams.ATTACKING_ENTITY, nmsDamageSource.entity) + .withOptionalParameter( + LootContextParams.DIRECT_ATTACKING_ENTITY, + nmsDamageSource.directEntity + ) + + val lastHurtByPlayer = nmsEntity.getLastHurtByPlayer() + if (causedByPlayer && lastHurtByPlayer != null) { + lootParamsBuilder.withParameter(LootContextParams.LAST_DAMAGE_PLAYER, lastHurtByPlayer) + .withLuck(lastHurtByPlayer.luck) + } + + val lootParams = lootParamsBuilder.create(LootContextParamSets.ENTITY) + return lootTable.getRandomItems(lootParams, nmsEntity.lootTableSeed) + .mapTo(mutableObjectListOf()) { it.toBukkit() } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsNbtBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsNbtBridgeImpl.kt new file mode 100644 index 000000000..ab61073e0 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsNbtBridgeImpl.kt @@ -0,0 +1,63 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.bridges + +import dev.slne.surf.api.core.util.logger +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsNbtBridge +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toBukkit +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toNms +import net.minecraft.core.component.DataComponentPatch +import net.minecraft.core.component.DataComponents +import net.minecraft.nbt.CompoundTag +import net.minecraft.world.item.component.CustomData +import net.minecraft.world.item.component.TypedEntityData +import org.bukkit.entity.EntityType +import org.bukkit.inventory.ItemStack +import kotlin.jvm.optionals.getOrNull + +@NmsUseWithCaution +class V26_1SurfPaperNmsNbtBridgeImpl : SurfPaperNmsNbtBridge { + + private val log = logger() + + override fun makeItemStackEntityInvisible( + itemStack: ItemStack, + invisibleEntityType: EntityType, + ): ItemStack { + val nmsStack = itemStack.toNms() + + val nbt = CompoundTag() + nbt.putBoolean("Invisible", true) + nbt.putString("id", invisibleEntityType.key.asString()) + + val entityData = TypedEntityData.decodeEntity(nbt) + + val patch = DataComponentPatch.builder() + .set(DataComponents.ENTITY_DATA, entityData) + .build() + + nmsStack.applyComponents(patch) + + return nmsStack.toBukkit() + } + + @Suppress("OVERRIDE_DEPRECATION", "DEPRECATION") + override fun getNbtString( + itemStack: ItemStack, + key: String, + ): String { + log.atWarning() + .atMostEvery(30, java.util.concurrent.TimeUnit.SECONDS) + .log( + ("Using deprecated method getNbtString(ItemStack, String) in SurfBukkitNmsNbtBridgeImpl." + + " ItemStacks now use DataComponents and nbt keys are not used. Please update your" + + " code to use DataComponents instead.") + ) + + return itemStack.toNms().components + .getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY) + .unsafe + .getString(key) + .getOrNull() + ?: "{}" + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsStatsBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsStatsBridgeImpl.kt new file mode 100644 index 000000000..72e50466e --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsStatsBridgeImpl.kt @@ -0,0 +1,21 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.bridges + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsStatsBridge +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toNms +import dev.slne.surf.api.paper.server.nms.v26_1.reflection.V26_1Reflection +import org.bukkit.entity.Player + +@NmsUseWithCaution +class V26_1SurfPaperNmsStatsBridgeImpl : SurfPaperNmsStatsBridge { + + override fun getPlayerStatsAsJson(player: Player): String { + val gson = V26_1Reflection.SERVER_STATS_COUNTER_PROXY.getGson() + val jsonElement = V26_1Reflection.SERVER_STATS_COUNTER_PROXY.toJson(player.toNms().stats) + return gson.toJson(jsonElement) + } + + override fun savePlayerStatsToFile(player: Player) { + player.toNms().stats.save() + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/V26_1PacketOperationImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/V26_1PacketOperationImpl.kt new file mode 100644 index 000000000..18596ab35 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/V26_1PacketOperationImpl.kt @@ -0,0 +1,115 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets + +import com.google.common.flogger.FluentLogger +import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toNms +import net.minecraft.network.protocol.Packet +import net.minecraft.network.protocol.game.ClientGamePacketListener +import net.minecraft.network.protocol.game.ClientboundBundlePacket +import org.bukkit.entity.Player +import java.util.* + +class V26_1PacketOperationImpl : PacketOperation { + private var operation: Operation + + private constructor(operation: Operation) { + this.operation = operation + } + + private constructor() { + this.operation = Operation.empty() + } + + override fun execute(player: Player) { + val connection = player.toNms().connection + val packets = operation.apply( + player, + LinkedList>() + ) + + if (packets.isEmpty()) { + return + } + + if (packets.size == 1) { + connection.send(packets.first()) + return + } + + connection.send(ClientboundBundlePacket(packets)) + } + + override fun add(operation: PacketOperation): V26_1PacketOperationImpl { + require(operation is V26_1PacketOperationImpl) { "operation must be an instance of V26_1PacketOperationImpl" } + + this.operation = this.operation.andThen(operation.operation) + return this + } + + override fun isEmpty(): Boolean { + val operation = operation + return operation is EmptyOperation && operation.empty + } + + fun interface Operation { + fun apply( + player: Player, + packets: LinkedList>, + ): LinkedList> + + fun andThen(after: Operation): Operation { + return Operation { player, packets -> + after.apply(player, apply(player, packets)) + } + } + + companion object { + fun empty() = EmptyOperation() + } + } + + class EmptyOperation : Operation { + var empty: Boolean = true + private set + + override fun apply( + player: Player, + packets: LinkedList>, + ): LinkedList> { + return packets + } + + override fun andThen(after: Operation): Operation { + empty = false + return super.andThen(after) + } + } + + companion object { + private val logger: FluentLogger = FluentLogger.forEnclosingClass() + + @JvmStatic + fun empty(): V26_1PacketOperationImpl { + return V26_1PacketOperationImpl() + } + + @JvmStatic + fun complex(operation: Operation): V26_1PacketOperationImpl { + return V26_1PacketOperationImpl(operation) + } + + fun simple(packetSupplier: (Player) -> Packet): V26_1PacketOperationImpl { + return V26_1PacketOperationImpl { player, packets -> + packets.add(packetSupplier(player)) + packets + } + } + + fun task(task: (Player) -> Unit): V26_1PacketOperationImpl { + return V26_1PacketOperationImpl { player, packets -> + task(player) + packets + } + } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/V26_1SurfPaperNmsPacketBridgesImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/V26_1SurfPaperNmsPacketBridgesImpl.kt new file mode 100644 index 000000000..0382b2342 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/V26_1SurfPaperNmsPacketBridgesImpl.kt @@ -0,0 +1,12 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.SurfPaperNmsPacketBridges + +@NmsUseWithCaution +class V26_1SurfPaperNmsPacketBridgesImpl : SurfPaperNmsPacketBridges { + + override fun createEmptyPacketOperation(): V26_1PacketOperationImpl { + return V26_1PacketOperationImpl.empty() + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/block/V26_1SurfPaperNmsBlockPacketsImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/block/V26_1SurfPaperNmsBlockPacketsImpl.kt new file mode 100644 index 000000000..e36db8fd1 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/block/V26_1SurfPaperNmsBlockPacketsImpl.kt @@ -0,0 +1,31 @@ +@file:Suppress("UnstableApiUsage") + +package dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.block + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.block.SurfPaperNmsBlockPackets +import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.V26_1PacketOperationImpl +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toNms +import io.papermc.paper.math.BlockPosition +import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket +import org.bukkit.block.data.BlockData + +@NmsUseWithCaution +class V26_1SurfPaperNmsBlockPacketsImpl : SurfPaperNmsBlockPackets { + + override fun updateBlockData(position: BlockPosition, blockData: BlockData) = + V26_1PacketOperationImpl.simple { + ClientboundBlockUpdatePacket( + position.toNms(), + blockData.toNms() + ) + } + + + override fun resetBlock(position: BlockPosition) = V26_1PacketOperationImpl.simple { + ClientboundBlockUpdatePacket( + it.toNms().level(), + position.toNms() + ) + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/entity/V26_1SurfPaperNmsSpawnPacketsImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/entity/V26_1SurfPaperNmsSpawnPacketsImpl.kt new file mode 100644 index 000000000..fe2491b85 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/entity/V26_1SurfPaperNmsSpawnPacketsImpl.kt @@ -0,0 +1,207 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.entity + +import com.google.common.flogger.StackSize +import com.mojang.math.Transformation +import dev.slne.surf.api.core.util.logger +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.entity.* +import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.V26_1PacketOperationImpl +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toNms +import io.papermc.paper.math.BlockPosition +import io.papermc.paper.math.FinePosition +import it.unimi.dsi.fastutil.ints.IntList +import net.minecraft.core.HolderLookup +import net.minecraft.nbt.CompoundTag +import net.minecraft.nbt.NbtOps +import net.minecraft.network.protocol.game.* +import net.minecraft.server.MinecraftServer +import net.minecraft.world.entity.Display +import net.minecraft.world.entity.Entity +import net.minecraft.world.entity.EntityType +import net.minecraft.world.entity.PositionMoveRotation +import net.minecraft.world.level.block.entity.BlockEntityType +import net.minecraft.world.level.block.entity.SignText +import net.minecraft.world.phys.Vec3 +import org.bukkit.entity.TextDisplay.TextAlignment +import kotlin.experimental.and +import kotlin.experimental.inv +import kotlin.experimental.or + +@Suppress("UnstableApiUsage") +@NmsUseWithCaution +class V26_1SurfPaperNmsSpawnPacketsImpl : SurfPaperNmsSpawnPackets { + private val log = logger() + + override fun despawn(entityIds: IntList) = + V26_1PacketOperationImpl.simple { ClientboundRemoveEntitiesPacket(entityIds) } + + override fun despawn(vararg entityId: Int) = + V26_1PacketOperationImpl.simple { ClientboundRemoveEntitiesPacket(*entityId) } + + + override fun spawnItemDisplay( + entityId: Int, + position: FinePosition, + settings: ItemDisplaySettings, + ) = V26_1PacketOperationImpl.complex { player, packets -> + val serverPlayer = player.toNms() + val display = Display.ItemDisplay(EntityType.ITEM_DISPLAY, serverPlayer.level()).apply { + id = entityId + + setPosition(position) + applySettings(settings) + + itemStack = settings.itemStack.toNms() + itemTransform = settings.itemDisplayTransform.toNms() + } + + packets.add(ClientboundAddEntityPacket(display, 0, display.blockPosition())) + packets.add(createSetEntityDataPacket(entityId, display)) + packets + } + + override fun spawnTextDisplay( + entityId: Int, + position: FinePosition, + settings: TextDisplaySettings, + ) = V26_1PacketOperationImpl.complex { player, packets -> + val serverPlayer = player.toNms() + val display = Display.TextDisplay(EntityType.TEXT_DISPLAY, serverPlayer.level()).apply { + id = entityId + + setPosition(position) + applySettings(settings) + + text = settings.text.toNms() + + val data = getEntityData() + data[Display.TextDisplay.DATA_LINE_WIDTH_ID] = settings.lineWidth + data[Display.TextDisplay.DATA_BACKGROUND_COLOR_ID] = settings.backgroundColor.value() + + when (settings.textAlignment) { + TextAlignment.CENTER -> { + setFlag(Display.TextDisplay.FLAG_ALIGN_LEFT, false) + setFlag(Display.TextDisplay.FLAG_ALIGN_RIGHT, false) + } + + TextAlignment.LEFT -> { + setFlag(Display.TextDisplay.FLAG_ALIGN_LEFT, true) + setFlag(Display.TextDisplay.FLAG_ALIGN_RIGHT, false) + } + + TextAlignment.RIGHT -> { + setFlag(Display.TextDisplay.FLAG_ALIGN_LEFT, false) + setFlag(Display.TextDisplay.FLAG_ALIGN_RIGHT, true) + } + } + } + + + packets.add(ClientboundAddEntityPacket(display, 0, display.blockPosition())) + packets.add(createSetEntityDataPacket(entityId, display)) + packets + } + + override fun updateSign( + entityId: Int, + position: BlockPosition, + settings: SignBlockUpdateSettings, + ) = V26_1PacketOperationImpl.complex { player, packets -> + val nbt = CompoundTag() + val registryLookup = MinecraftServer.getServer().registryAccess() + writeUpdateSignToTag(nbt, registryLookup, settings.frontText, settings.backText) + + packets.add(ClientboundBlockEntityDataPacket(position.toNms(), BlockEntityType.SIGN, nbt)) + packets + } + + override fun spawnBlockDisplay( + entityId: Int, + position: FinePosition, + settings: BlockDisplaySettings, + ) = V26_1PacketOperationImpl.complex { player, packets -> + val serverPlayer = player.toNms() + val display = Display.BlockDisplay(EntityType.BLOCK_DISPLAY, serverPlayer.level()).apply { + id = entityId + + setPosition(position) + applySettings(settings) + blockState = settings.blockData.toNms() + } + + packets.add(ClientboundAddEntityPacket(display, 0, display.blockPosition())) + packets.add(createSetEntityDataPacket(entityId, display)) + packets + } + + override fun teleport( + entityId: Int, + position: FinePosition, + yaw: Float, + pitch: Float, + deltaMovement: FinePosition?, + onGround: Boolean, + ) = V26_1PacketOperationImpl.simple { + ClientboundTeleportEntityPacket.teleport( + entityId, + PositionMoveRotation(position.toNms(), deltaMovement?.toNms() ?: Vec3.ZERO, yaw, pitch), + emptySet(), + onGround + ) + } + + private fun createSetEntityDataPacket(entityId: Int, entity: Entity) = + ClientboundSetEntityDataPacket(entityId, entity.getEntityData().packAll()) + + private fun writeUpdateSignToTag( + nbt: CompoundTag, + registryLookup: HolderLookup.Provider, + frontText: SignBlockUpdateSettings.SignText, + backText: SignBlockUpdateSettings.SignText, + ) { + writeTextToTag(nbt, registryLookup, frontText, "front_text", true) + writeTextToTag(nbt, registryLookup, backText, "back_text", false) + } + + private fun writeTextToTag( + nbt: CompoundTag, + registryLookup: HolderLookup.Provider, + text: SignBlockUpdateSettings.SignText, + tagText: String, + isFrontText: Boolean, + ) { + val nbtOps = registryLookup.createSerializationContext(NbtOps.INSTANCE) + val textTag = SignText.DIRECT_CODEC.encodeStart(nbtOps, text.toNms()) + textTag.resultOrPartial { logFailedEncodeText(it, isFrontText) } + .ifPresent { nbt.put(tagText, it) } + } + + private fun logFailedEncodeText(string: String, front: Boolean) { + log.atSevere() + .withStackTrace(StackSize.MEDIUM) + .atMostEvery(5, java.util.concurrent.TimeUnit.SECONDS) + .log("Failed to encode %s text: %s", if (front) "front" else "back", string) + } + + private fun getTransformation(settings: DisplaySettings) = Transformation( + settings.translation.toNms(), + settings.leftRotation.toNms(), + settings.scale.toNms(), + settings.rightRotation.toNms() + ) + + private fun Display.applySettings(settings: DisplaySettings) { + xRot = settings.pitch + yRot = settings.yaw + setTransformation(getTransformation(settings)) + billboardConstraints = settings.billboardConstraints.toNms() + } + + private fun Entity.setPosition(position: FinePosition) { + setPosRaw(position.x(), position.y(), position.z()) + } + + private fun Display.TextDisplay.setFlag(flag: Byte, set: Boolean) { + flags = if (set) flags or flag else flags and flag.inv() + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerChatPacketsImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerChatPacketsImpl.kt new file mode 100644 index 000000000..5fbfe4a2a --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerChatPacketsImpl.kt @@ -0,0 +1,64 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.player + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation +import dev.slne.surf.api.paper.nms.bridges.packets.player.LastSeenMessagesPacked +import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerChatPackets +import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.V26_1PacketOperationImpl +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toNms +import net.kyori.adventure.chat.SignedMessage +import net.kyori.adventure.text.Component +import net.minecraft.network.chat.ChatType +import net.minecraft.network.chat.FilterMask +import net.minecraft.network.chat.LastSeenMessages +import net.minecraft.network.chat.SignedMessageBody +import net.minecraft.network.protocol.game.ClientboundPlayerChatPacket +import net.minecraft.server.MinecraftServer +import java.time.Instant +import java.util.* +import net.minecraft.network.chat.MessageSignature as NmsMessageSignature + +@NmsUseWithCaution +class V26_1SurfPaperNmsPlayerChatPacketsImpl : SurfPaperNmsPlayerChatPackets { + override fun sendPlayerChatMessagePacket( + senderUuid: UUID, + senderDisplayName: Component, + globalIndex: Int, + index: Int, + signature: SignedMessage.Signature?, + salt: Long, + timestamp: Instant, + content: String, + unsignedContent: Component?, + lastSeen: LastSeenMessagesPacked, + ): PacketOperation = V26_1PacketOperationImpl.simple { player -> + val messageSignature = signature?.let { NmsMessageSignature(it.bytes()) } + val signedBody = SignedMessageBody.Packed(content, timestamp, salt, lastSeen.toNms()) + + ClientboundPlayerChatPacket( + globalIndex, + senderUuid, + index, + messageSignature, + signedBody, + unsignedContent?.toNms(), + FilterMask.PASS_THROUGH, + ChatType.bind( + ChatType.CHAT, + MinecraftServer.getServer().registryAccess(), + senderDisplayName.toNms() + ) + ) + } + + private fun LastSeenMessagesPacked.toNms(): LastSeenMessages.Packed { + val list = mutableListOf() + + for ((id, signature) in this) { + val nmsSignature = signature?.let { NmsMessageSignature(it.bytes()) } + list.add(NmsMessageSignature.Packed(id, nmsSignature)) + } + + return LastSeenMessages.Packed(list) + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerPacketsImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerPacketsImpl.kt new file mode 100644 index 000000000..5abfb7fce --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerPacketsImpl.kt @@ -0,0 +1,54 @@ +@file:Suppress("UnstableApiUsage") + +package dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.player + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerPackets +import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.V26_1PacketOperationImpl +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toNms +import io.papermc.paper.math.BlockPosition +import net.kyori.adventure.text.Component +import net.minecraft.network.protocol.game.ClientboundContainerClosePacket +import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket +import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket +import net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket +import org.bukkit.event.inventory.InventoryType +import org.bukkit.inventory.ItemStack + +@NmsUseWithCaution +class V26_1SurfPaperNmsPlayerPacketsImpl : SurfPaperNmsPlayerPackets { + + override fun openSignEditor( + position: BlockPosition, + frontSide: Boolean, + ) = V26_1PacketOperationImpl.simple { ClientboundOpenSignEditorPacket(position.toNms(), frontSide) } + + override fun openInventory( + syncId: Int, + type: InventoryType, + title: Component, + ) = V26_1PacketOperationImpl.simple { + ClientboundOpenScreenPacket( + syncId, + type.toNms(), + title.toNms() + ) + } + + override fun setInventorySlot( + syncId: Int, + revision: Int, + slot: Int, + item: ItemStack, + ) = V26_1PacketOperationImpl.simple { + ClientboundContainerSetSlotPacket( + syncId, + revision, + slot, + item.toNms() + ) + } + + override fun closeInventory(syncId: Int) = + V26_1PacketOperationImpl.simple { ClientboundContainerClosePacket(syncId) } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerToastPacketsImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerToastPacketsImpl.kt new file mode 100644 index 000000000..97f6e1d7d --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerToastPacketsImpl.kt @@ -0,0 +1,60 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.player + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToastPackets +import dev.slne.surf.api.paper.nms.bridges.packets.player.toast.Toast +import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.V26_1PacketOperationImpl +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toNms +import net.minecraft.advancements.Advancement +import net.minecraft.advancements.AdvancementProgress +import net.minecraft.advancements.AdvancementRequirements +import net.minecraft.network.chat.Component +import net.minecraft.network.protocol.game.ClientboundUpdateAdvancementsPacket +import net.minecraft.resources.Identifier +import java.util.* + + +@NmsUseWithCaution +class V26_1SurfPaperNmsPlayerToastPacketsImpl : SurfPaperNmsPlayerToastPackets { + override fun showToast(toast: Toast) = V26_1PacketOperationImpl.complex { _, packets -> + val id = Identifier.fromNamespaceAndPath("surfapi", "toast_${UUID.randomUUID()}") + + packets.add(showPacket(id, toast)) + packets.add(hidePacket(id)) + + packets + } + + private fun showPacket(id: Identifier, toast: Toast) = + ClientboundUpdateAdvancementsPacket( + false, listOf(createAdvancement(id, toast)), emptySet(), mapOf( + id to AdvancementProgress().apply { + update(requirements) + grantProgress(CRITERION_ID) + }), true + ) + + private fun hidePacket(id: Identifier) = ClientboundUpdateAdvancementsPacket( + false, emptyList(), setOf(id), emptyMap(), false + ) + + private fun createAdvancement(id: Identifier, toast: Toast) = + Advancement.Builder.recipeAdvancement() + .display( + toast.icon.toNms().item, + toast.title.toNms(), + Component.empty(), + null, + toast.frame.toNms(), + true, + false, + false + ) + .requirements(requirements) + .build(id) + + companion object { + private const val CRITERION_ID = "surfapi_toast" + private val requirements by lazy { AdvancementRequirements.allOf(listOf(CRITERION_ID)) } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/extensions/AdventureNBT.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/extensions/AdventureNBT.kt new file mode 100644 index 000000000..2b7c4c305 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/extensions/AdventureNBT.kt @@ -0,0 +1,96 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.extensions + +import net.kyori.adventure.nbt.* +import net.minecraft.nbt.* + +object AdventureNBT { + fun toNms( + adventure: CompoundBinaryTag, + accounter: NbtAccounter = NbtAccounter.unlimitedHeap() + ): CompoundTag { + return CompoundTag().also { tag -> + for ((key, value) in adventure) { + tag.put(key, toNms(value, accounter)) + } + } + } + + fun toNms( + adventure: BinaryTag, + accounter: NbtAccounter = NbtAccounter.unlimitedHeap() + ): Tag { + accounter.pushDepth() + + val nmsTag = when (adventure) { + is IntBinaryTag -> IntTag.valueOf(adventure.value()) + is ByteBinaryTag -> ByteTag.valueOf(adventure.value()) + is FloatBinaryTag -> FloatTag.valueOf(adventure.value()) + is LongBinaryTag -> LongTag.valueOf(adventure.value()) + is DoubleBinaryTag -> DoubleTag.valueOf(adventure.value()) + is ShortBinaryTag -> ShortTag.valueOf(adventure.value()) + is StringBinaryTag -> StringTag.valueOf(adventure.value()) + is ByteArrayBinaryTag -> ByteArrayTag(adventure.value()) + is IntArrayBinaryTag -> IntArrayTag(adventure.value()) + is LongArrayBinaryTag -> LongArrayTag(adventure.value()) + is EndBinaryTag -> EndTag.INSTANCE + is ListBinaryTag -> if (adventure.isEmpty) { + ListTag() + } else { + val list = ListTag() + for (entry in adventure) { + val nms = toNms(entry) + list.add(nms) + } + list + } + + is CompoundBinaryTag -> { + val tag = CompoundTag() + for ((key, entry) in adventure) { + val nms = toNms(entry) + tag.put(key, nms) + } + tag + } + + else -> throw IllegalArgumentException("Unsupported tag type: ${adventure::class}") + } + + accounter.popDepth() + + return nmsTag + } + + fun fromNms(nms: CompoundTag): CompoundBinaryTag = CompoundBinaryTag.builder().also { builder -> + nms.forEach { key, tag -> builder.put(key, fromNms(tag)) } + }.build() + + fun fromNms(nms: Tag): BinaryTag = when (nms) { + is IntTag -> IntBinaryTag.intBinaryTag(nms.intValue()) + is ByteTag -> ByteBinaryTag.byteBinaryTag(nms.byteValue()) + is FloatTag -> FloatBinaryTag.floatBinaryTag(nms.floatValue()) + is LongTag -> LongBinaryTag.longBinaryTag(nms.longValue()) + is DoubleTag -> DoubleBinaryTag.doubleBinaryTag(nms.doubleValue()) + is ShortTag -> ShortBinaryTag.shortBinaryTag(nms.shortValue()) + is StringTag -> StringBinaryTag.stringBinaryTag(nms.value()) + is ByteArrayTag -> ByteArrayBinaryTag.byteArrayBinaryTag(*nms.asByteArray) + is IntArrayTag -> IntArrayBinaryTag.intArrayBinaryTag(*nms.asIntArray) + is LongArrayTag -> LongArrayBinaryTag.longArrayBinaryTag(*nms.asLongArray) + is EndTag -> EndBinaryTag.endBinaryTag() + is ListTag -> { + val tag = ListBinaryTag.heterogeneousListBinaryTag() + for (t in nms) { + tag.add(fromNms(t)) + } + tag.build() + } + + is CompoundTag -> { + val adventure = CompoundBinaryTag.builder() + nms.forEach { key, tag -> + adventure.put(key, fromNms(tag)) + } + adventure.build() + } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/extensions/nms-extensions.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/extensions/nms-extensions.kt new file mode 100644 index 000000000..5fce86c03 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/extensions/nms-extensions.kt @@ -0,0 +1,150 @@ +@file:Suppress("UnstableApiUsage") + +package dev.slne.surf.api.paper.server.nms.v26_1.extensions + +import dev.slne.surf.api.paper.extensions.server +import dev.slne.surf.api.paper.nms.bridges.packets.entity.SignBlockUpdateSettings +import io.papermc.paper.advancement.AdvancementDisplay +import io.papermc.paper.advancement.AdvancementDisplay.Frame.* +import io.papermc.paper.adventure.PaperAdventure +import io.papermc.paper.math.BlockPosition +import io.papermc.paper.math.FinePosition +import io.papermc.paper.math.Position +import net.minecraft.advancements.AdvancementType +import net.minecraft.core.BlockPos +import net.minecraft.core.Holder +import net.minecraft.network.chat.Component +import net.minecraft.server.level.ServerLevel +import net.minecraft.server.level.ServerPlayer +import net.minecraft.world.entity.Display +import net.minecraft.world.inventory.MenuType +import net.minecraft.world.item.DyeColor +import net.minecraft.world.item.Item +import net.minecraft.world.item.ItemDisplayContext +import net.minecraft.world.level.block.Block +import net.minecraft.world.level.block.entity.SignText +import net.minecraft.world.phys.Vec3 +import org.bukkit.Material +import org.bukkit.Server +import org.bukkit.World +import org.bukkit.block.BlockState +import org.bukkit.block.data.BlockData +import org.bukkit.craftbukkit.CraftServer +import org.bukkit.craftbukkit.CraftWorld +import org.bukkit.craftbukkit.block.CraftBlockState +import org.bukkit.craftbukkit.block.data.CraftBlockData +import org.bukkit.craftbukkit.damage.CraftDamageSource +import org.bukkit.craftbukkit.entity.CraftEntity +import org.bukkit.craftbukkit.entity.CraftEntityType +import org.bukkit.craftbukkit.entity.CraftLivingEntity +import org.bukkit.craftbukkit.entity.CraftPlayer +import org.bukkit.craftbukkit.inventory.CraftItemStack +import org.bukkit.craftbukkit.inventory.CraftItemType +import org.bukkit.craftbukkit.util.Commodore +import org.bukkit.craftbukkit.util.CraftMagicNumbers +import org.bukkit.damage.DamageSource +import org.bukkit.entity.Display.Billboard +import org.bukkit.entity.Entity +import org.bukkit.entity.EntityType +import org.bukkit.entity.ItemDisplay.ItemDisplayTransform +import org.bukkit.entity.LivingEntity +import org.bukkit.entity.Player +import org.bukkit.event.inventory.InventoryType +import org.bukkit.inventory.ItemStack +import org.bukkit.inventory.ItemType +import org.spongepowered.math.imaginary.Quaternionf +import org.spongepowered.math.vector.Vector3f +import net.kyori.adventure.text.Component as AdventureComponent +import net.minecraft.world.item.ItemStack as NmsItemStack +import net.minecraft.world.level.block.state.BlockState as NmsBlockState +import org.joml.Quaternionf as NmsQuaternionf +import org.joml.Vector3f as NmsVector3f + +fun Player.toNms(): ServerPlayer = (this as CraftPlayer).handle +fun Material.toNmsBlock(): Block = CraftMagicNumbers.getBlock(this) +fun Material.toNmsItem(): Item = CraftMagicNumbers.getItem(this) +fun BlockData.toNms(): NmsBlockState = (this as CraftBlockData).state +fun Vector3f?.toNms(): NmsVector3f? = + if (this == null) null else NmsVector3f(this.x(), this.y(), this.z()) + +fun FinePosition.toNms() = Vec3(x(), y(), z()) +fun BlockState.toNms(): NmsBlockState = (this as CraftBlockState).handle +fun Quaternionf?.toNms(): NmsQuaternionf? = + if (this == null) null else NmsQuaternionf(x(), y(), z(), w()) + +fun Billboard.toNms(): Display.BillboardConstraints = + Display.BillboardConstraints.valueOf(this.name) + +fun ItemStack.toNms(): NmsItemStack = CraftItemStack.asNMSCopy(this) +fun ItemDisplayTransform.toNms(): ItemDisplayContext = ItemDisplayContext.BY_ID.apply(this.ordinal) +fun NmsItemStack.toBukkit(): ItemStack = CraftItemStack.asBukkitCopy(this) +val ItemType.nms: Item get() = CraftItemType.bukkitToMinecraftNew(this) +fun BlockPosition.toNms(): BlockPos = BlockPos(blockX(), blockY(), blockZ()) +fun SignBlockUpdateSettings.SignText.toNms(): SignText { + val lines = arrayOf( + line1.toNms(), + line2.toNms(), + line3.toNms(), + line4.toNms() + ) + + return SignText(lines, lines, DyeColor.BLACK, false) +} + +fun InventoryType.toNms(): MenuType<*> = when (this) { + InventoryType.ANVIL -> MenuType.ANVIL + InventoryType.BEACON -> MenuType.BEACON + InventoryType.BLAST_FURNACE -> MenuType.BLAST_FURNACE + InventoryType.BREWING -> MenuType.BREWING_STAND + InventoryType.CARTOGRAPHY -> MenuType.CARTOGRAPHY_TABLE + InventoryType.CHEST -> MenuType.GENERIC_9x6 + InventoryType.DISPENSER, InventoryType.DROPPER -> MenuType.GENERIC_3x3 + InventoryType.ENCHANTING -> MenuType.ENCHANTMENT + InventoryType.FURNACE -> MenuType.FURNACE + InventoryType.GRINDSTONE -> MenuType.GRINDSTONE + InventoryType.HOPPER -> MenuType.HOPPER + InventoryType.LECTERN -> MenuType.LECTERN + InventoryType.LOOM -> MenuType.LOOM + InventoryType.MERCHANT -> MenuType.MERCHANT + InventoryType.SHULKER_BOX -> MenuType.SHULKER_BOX + InventoryType.SMOKER -> MenuType.SMOKER + InventoryType.SMITHING -> MenuType.SMITHING + InventoryType.STONECUTTER -> MenuType.STONECUTTER + InventoryType.PLAYER -> MenuType.GENERIC_9x4 + InventoryType.CRAFTER -> MenuType.CRAFTER_3x3 + InventoryType.WORKBENCH -> MenuType.CRAFTING + InventoryType.BARREL, InventoryType.CHISELED_BOOKSHELF, InventoryType.DECORATED_POT, InventoryType.JUKEBOX, InventoryType.COMPOSTER, InventoryType.ENDER_CHEST -> MenuType.GENERIC_9x3 + InventoryType.CREATIVE, InventoryType.CRAFTING -> throw UnsupportedOperationException("Can't open a $this inventory!") + else -> throw UnsupportedOperationException("Unknown inventory type: $this") +} + +fun BlockPos.toBukkit(): BlockPosition = Position.block(x, y, z) + +fun Array.toBukkit() = this.map { it.toBukkit() } +fun AdventureComponent.toNms(): Component = PaperAdventure.asVanilla(this) +fun Component.toBukkit(): AdventureComponent = PaperAdventure.asAdventure(this) + +fun Server.toCraft() = this as CraftServer +val craftServer: CraftServer get() = server.toCraft() +val commodore: Commodore get() = CraftMagicNumbers.INSTANCE.commodore + +fun EntityType.toNms(): net.minecraft.world.entity.EntityType<*> = + CraftEntityType.bukkitToMinecraft(this) + +@Suppress("DEPRECATION") +fun EntityType.toNmsHolder() = + CraftEntityType.bukkitToMinecraftHolder(this) as Holder.Reference> + +fun World.toNms(): ServerLevel = (this as CraftWorld).handle +fun Entity.toNms(): net.minecraft.world.entity.Entity = (this as CraftEntity).handleRaw +fun LivingEntity.toNms(): net.minecraft.world.entity.LivingEntity = + (this as CraftLivingEntity).handle + +fun DamageSource.toNms(): net.minecraft.world.damagesource.DamageSource = + (this as CraftDamageSource).handle + +fun AdvancementDisplay.Frame.toNms() = when (this) { + CHALLENGE -> AdvancementType.CHALLENGE + GOAL -> AdvancementType.GOAL + TASK -> AdvancementType.TASK +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1TeamData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1TeamData.kt new file mode 100644 index 000000000..071a53285 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1TeamData.kt @@ -0,0 +1,40 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.glow + +import net.minecraft.ChatFormatting +import net.minecraft.world.scores.PlayerTeam +import net.minecraft.world.scores.Scoreboard +import net.minecraft.world.scores.Team +import java.util.* +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.atomic.AtomicInteger + +class V26_1TeamData(color: ChatFormatting) { + private val scoreboard = Scoreboard() + val teamId = "glow-${uid()}${color.char}" + val team = PlayerTeam(scoreboard, teamId).apply { + collisionRule = Team.CollisionRule.NEVER + this.color = color + } + + private val seenBy = ConcurrentHashMap.newKeySet() + + fun markSeen(uniqueId: UUID) = seenBy.add(uniqueId) + fun isSeen(uniqueId: UUID): Boolean = seenBy.contains(uniqueId) + fun removeSeen(uniqueId: UUID) = seenBy.remove(uniqueId) + + companion object { + private val lastUid = AtomicInteger() + fun uid(): Int = lastUid.getAndIncrement() + + private val teams = EnumMap(ChatFormatting::class.java) + + fun getByColor(color: ChatFormatting): V26_1TeamData = + teams.computeIfAbsent(color) { V26_1TeamData(color) } + + fun getByColorOrNull(color: ChatFormatting): V26_1TeamData? = teams[color] + + fun removeFromAll(uuid: UUID) { + teams.values.forEach { it.removeSeen(uuid) } + } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/V26_1BlockGlowingData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/V26_1BlockGlowingData.kt new file mode 100644 index 000000000..5ab0b9474 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/V26_1BlockGlowingData.kt @@ -0,0 +1,81 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.glow.block + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsCommonBridge +import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation +import dev.slne.surf.api.paper.nms.bridges.packets.entity.SurfPaperNmsSpawnPackets +import dev.slne.surf.api.paper.server.impl.glow.SurfGlowingApiImpl +import dev.slne.surf.api.paper.server.impl.glow.block.BlockPlayerData +import dev.slne.surf.api.paper.server.nms.v26_1.bridges.V26_1SurfPaperNmsGlowingBridgeImpl +import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.V26_1PacketOperationImpl +import dev.slne.surf.api.paper.server.nms.v26_1.reflection.V26_1Reflection +import glm_.shl +import net.kyori.adventure.text.format.NamedTextColor +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket +import net.minecraft.world.entity.EntityType +import net.minecraft.world.phys.Vec3 +import org.bukkit.Location +import java.util.* + +@OptIn(NmsUseWithCaution::class) +class V26_1BlockGlowingData( + val playerData: BlockPlayerData, + val location: Location, + var color: NamedTextColor, +) { + + private val entityId: Int by lazy { SurfPaperNmsCommonBridge.nextEntityId() } + private val uuid: UUID by lazy { UUID.randomUUID() } + private var initialized = false + + fun spawn(): PacketOperation { + initialize() + + val spawnOperation = V26_1PacketOperationImpl.simple { + ClientboundAddEntityPacket( + entityId, + uuid, + location.x, + location.y, + location.z, + location.pitch, + location.yaw, + EntityType.SHULKER, + 0, + Vec3.ZERO, + 0.0 + ) + } + val invisibleOperation = V26_1SurfPaperNmsGlowingBridgeImpl.INSTANCE + .setEntityFlags(entityId, invisibleFlag) + + return spawnOperation + invisibleOperation + } + + + fun updateColor() { + val player = playerData.player ?: return + SurfGlowingApiImpl.INSTANCE.makeGlowing( + entityId, + uuid.toString(), + player, + color, + invisibleFlag + ) + } + + fun remove() { + playerData.player?.let { SurfPaperNmsSpawnPackets.despawn(entityId).execute(it) } + SurfGlowingApiImpl.INSTANCE.removeGlowing(entityId, playerData.uuid) + } + + private fun initialize() { + if (initialized) return + initialized = true + updateColor() + } + + companion object { + val invisibleFlag = 1.toByte() shl V26_1Reflection.ENTITY_PROXY.getFlagInvisible() + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/V26_1NmsPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/V26_1NmsPacketImpl.kt new file mode 100644 index 000000000..0e9f028e4 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/V26_1NmsPacketImpl.kt @@ -0,0 +1,24 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.listener.packets + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.listener.packets.NmsPacket +import net.minecraft.network.PacketListener +import net.minecraft.network.protocol.Packet + +@NmsUseWithCaution +abstract class V26_1NmsPacketImpl, Listener : PacketListener>(var nmsPacket: Nms) : + NmsPacket { + val nmsClass = nmsPacket.javaClass + + override val packetClass = + javaClass.interfaces.find { NmsPacket::class.java.isAssignableFrom(it) } + ?: error("No packet interface found for ${javaClass.name}") + + companion object { + @JvmStatic + fun getFromApi(nmsPacket: NmsPacket): V26_1NmsPacketImpl<*, *> { + require(nmsPacket is V26_1NmsPacketImpl<*, *>) { "Invalid NmsPacket implementation: " + nmsPacket.javaClass.getName() } + return nmsPacket + } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/V26_1PacketRegistry.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/V26_1PacketRegistry.kt new file mode 100644 index 000000000..1e7a01666 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/V26_1PacketRegistry.kt @@ -0,0 +1,78 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.listener.packets + +import dev.slne.surf.api.core.util.mutableObject2ObjectMapOf +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.listener.packets.clientbound.NmsClientboundPacket +import dev.slne.surf.api.paper.nms.listener.packets.serverbound.NmsServerboundPacket +import dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.clientbound.V26_1ClientboundDisconnectPacketImpl +import dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.clientbound.V26_1ClientboundSystemChatPacketImpl +import dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.serverbound.V26_1CommandSuggestionPacketImpl +import dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.serverbound.V26_1RenameItemPacketImpl +import dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.serverbound.V26_1ServerboundCustomPayloadPacketImpl +import dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.serverbound.V26_1SignUpdatePacketImpl +import net.minecraft.network.protocol.Packet +import net.minecraft.network.protocol.common.ClientCommonPacketListener +import net.minecraft.network.protocol.common.ClientboundDisconnectPacket +import net.minecraft.network.protocol.common.ServerCommonPacketListener +import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket +import net.minecraft.network.protocol.game.ClientboundSystemChatPacket +import net.minecraft.network.protocol.game.ServerboundCommandSuggestionPacket +import net.minecraft.network.protocol.game.ServerboundRenameItemPacket +import net.minecraft.network.protocol.game.ServerboundSignUpdatePacket +import kotlin.reflect.KClass + +@OptIn(NmsUseWithCaution::class) +object V26_1PacketRegistry { + private val SERVERBOUND_PACKETS = + mutableObject2ObjectMapOf>, ServerboundPacketFactory<*, *>>() + private val CLIENTBOUND_PACKETS = + mutableObject2ObjectMapOf>, ClientboundPacketFactory<*, *>>() + + init { + // @formatter:off + // Serverbound packets + registerServerboundPacket(ServerboundSignUpdatePacket::class) { V26_1SignUpdatePacketImpl(it) } + registerServerboundPacket(ServerboundRenameItemPacket::class) { V26_1RenameItemPacketImpl(it) } + registerServerboundPacket(ServerboundCommandSuggestionPacket::class) { V26_1CommandSuggestionPacketImpl(it) } + registerServerboundPacket(ServerboundCustomPayloadPacket::class) { V26_1ServerboundCustomPayloadPacketImpl(it) } + + // Clientbound packets + registerClientboundPacket(ClientboundDisconnectPacket::class) { V26_1ClientboundDisconnectPacketImpl(it) } + registerClientboundPacket(ClientboundSystemChatPacket::class) { V26_1ClientboundSystemChatPacketImpl(it) } + // @formatter:on + } + + private fun , Api : NmsServerboundPacket> registerServerboundPacket( + nms: KClass, + factory: ServerboundPacketFactory, + ) { + SERVERBOUND_PACKETS[nms.java] = factory + } + + @Suppress("UNCHECKED_CAST") + fun > createServerboundPacketOrNull(packet: Nms): NmsServerboundPacket? { + val factory = SERVERBOUND_PACKETS[packet.javaClass] as? ServerboundPacketFactory + return factory?.create(packet) + } + + private fun , Api : NmsClientboundPacket, Listener : ClientCommonPacketListener> registerClientboundPacket( + nms: KClass, + factory: ClientboundPacketFactory, + ) { + CLIENTBOUND_PACKETS[nms.java] = factory + } + + @Suppress("UNCHECKED_CAST") + fun > createClientboundPacketOrNull(packet: Nms): NmsClientboundPacket? { + val factory = CLIENTBOUND_PACKETS[packet.javaClass] as? ClientboundPacketFactory + return factory?.create(packet) + } + + private fun interface ServerboundPacketFactory, Api : NmsServerboundPacket> { + fun create(packet: Nms): Api + } + + private fun interface ClientboundPacketFactory, Api : NmsClientboundPacket> { + fun create(packet: Nms): Api + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1ClientboundDisconnectPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1ClientboundDisconnectPacketImpl.kt new file mode 100644 index 000000000..450d88c84 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1ClientboundDisconnectPacketImpl.kt @@ -0,0 +1,14 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.clientbound + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.listener.packets.clientbound.DisconnectPacket +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toBukkit +import net.minecraft.network.protocol.common.ClientCommonPacketListener +import net.minecraft.network.protocol.common.ClientboundDisconnectPacket + +@NmsUseWithCaution +class V26_1ClientboundDisconnectPacketImpl(nmsPacket: ClientboundDisconnectPacket) : + V26_1NmsClientboundPacketImpl(nmsPacket), + DisconnectPacket { + override val reason get() = nmsPacket.reason.toBukkit() +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1ClientboundSystemChatPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1ClientboundSystemChatPacketImpl.kt new file mode 100644 index 000000000..1581c0f26 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1ClientboundSystemChatPacketImpl.kt @@ -0,0 +1,25 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.clientbound + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.listener.packets.clientbound.SystemChatPacket +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toBukkit +import net.kyori.adventure.text.Component +import net.minecraft.network.protocol.game.ClientGamePacketListener +import net.minecraft.network.protocol.game.ClientboundSystemChatPacket + +@NmsUseWithCaution +class V26_1ClientboundSystemChatPacketImpl(nmsPacket: ClientboundSystemChatPacket) : + V26_1NmsClientboundPacketImpl(nmsPacket), + SystemChatPacket { + override var content: Component + get() = nmsPacket.content().toBukkit() + set(value) { + nmsPacket = ClientboundSystemChatPacket(value, nmsPacket.overlay) + } + + override var overlay: Boolean + get() = nmsPacket.overlay() + set(value) { + nmsPacket = ClientboundSystemChatPacket(nmsPacket.content(), value) + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1NmsClientboundPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1NmsClientboundPacketImpl.kt new file mode 100644 index 000000000..9871fb6b3 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1NmsClientboundPacketImpl.kt @@ -0,0 +1,12 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.clientbound + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.listener.packets.clientbound.NmsClientboundPacket +import dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.V26_1NmsPacketImpl +import net.minecraft.network.protocol.Packet +import net.minecraft.network.protocol.common.ClientCommonPacketListener + +@NmsUseWithCaution +abstract class V26_1NmsClientboundPacketImpl, Listener : ClientCommonPacketListener>( + nmsPacket: Nms, +) : NmsClientboundPacket, V26_1NmsPacketImpl(nmsPacket) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1CommandSuggestionPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1CommandSuggestionPacketImpl.kt new file mode 100644 index 000000000..65c3c1e9f --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1CommandSuggestionPacketImpl.kt @@ -0,0 +1,13 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.serverbound + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.listener.packets.serverbound.CommandSuggestionPacket +import net.minecraft.network.protocol.game.ServerboundCommandSuggestionPacket + +@NmsUseWithCaution +class V26_1CommandSuggestionPacketImpl(nmsPacket: ServerboundCommandSuggestionPacket) : + V26_1NmsServerboundPacketImpl(nmsPacket), + CommandSuggestionPacket { + override val completionId get() = nmsPacket.id + override val command get() = nmsPacket.command +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1NmsServerboundPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1NmsServerboundPacketImpl.kt new file mode 100644 index 000000000..ba63b29f5 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1NmsServerboundPacketImpl.kt @@ -0,0 +1,10 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.serverbound + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.V26_1NmsPacketImpl +import net.minecraft.network.protocol.Packet +import net.minecraft.network.protocol.common.ServerCommonPacketListener + +@NmsUseWithCaution +abstract class V26_1NmsServerboundPacketImpl>(nmsPacket: Nms) : + V26_1NmsPacketImpl(nmsPacket) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1RenameItemPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1RenameItemPacketImpl.kt new file mode 100644 index 000000000..9638ad25f --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1RenameItemPacketImpl.kt @@ -0,0 +1,11 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.serverbound + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.listener.packets.serverbound.RenameItemPacket +import net.minecraft.network.protocol.game.ServerboundRenameItemPacket + +@NmsUseWithCaution +class V26_1RenameItemPacketImpl(nmsPacket: ServerboundRenameItemPacket) : + V26_1NmsServerboundPacketImpl(nmsPacket), RenameItemPacket { + override val newName: String get() = nmsPacket.name +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1ServerboundCustomPayloadPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1ServerboundCustomPayloadPacketImpl.kt new file mode 100644 index 000000000..d71c7efbe --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1ServerboundCustomPayloadPacketImpl.kt @@ -0,0 +1,42 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.serverbound + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import io.papermc.paper.adventure.PaperAdventure +import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket +import net.minecraft.network.protocol.common.custom.BrandPayload +import net.minecraft.network.protocol.common.custom.CustomPacketPayload +import net.minecraft.network.protocol.common.custom.DiscardedPayload +import dev.slne.surf.api.paper.nms.listener.packets.serverbound.ServerboundCustomPayloadPacket.Payload as ApiPayload + +@NmsUseWithCaution +class V26_1ServerboundCustomPayloadPacketImpl( + nmsPacket: ServerboundCustomPayloadPacket +) : V26_1NmsServerboundPacketImpl(nmsPacket), + dev.slne.surf.api.paper.nms.listener.packets.serverbound.ServerboundCustomPayloadPacket { + + override var payload: ApiPayload + get() = toApiPayload(nmsPacket.payload); + set(value) { + nmsPacket = ServerboundCustomPayloadPacket(toNmsPayload(value)) + } + + companion object { + private fun toApiPayload(nmsPayload: CustomPacketPayload): ApiPayload = when (nmsPayload) { + is BrandPayload -> ApiPayload.Brand(nmsPayload.brand) + is DiscardedPayload -> ApiPayload.Discarded( + id = PaperAdventure.asAdventure(nmsPayload.id), + data = nmsPayload.data + ) + + else -> error("Unknown CustomPacketPayload type: ${nmsPayload.type()}") + } + + private fun toNmsPayload(apiPayload: ApiPayload): CustomPacketPayload = when (apiPayload) { + is ApiPayload.Brand -> BrandPayload(apiPayload.brand) + is ApiPayload.Discarded -> DiscardedPayload( + PaperAdventure.asVanilla(apiPayload.id), + apiPayload.data + ) + } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1SignUpdatePacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1SignUpdatePacketImpl.kt new file mode 100644 index 000000000..782ccfd26 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1SignUpdatePacketImpl.kt @@ -0,0 +1,19 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.serverbound + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.listener.packets.serverbound.SignUpdatePacket +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toBukkit +import net.minecraft.network.protocol.game.ServerboundSignUpdatePacket + +@NmsUseWithCaution +class V26_1SignUpdatePacketImpl(nmsPacket: ServerboundSignUpdatePacket) : + V26_1NmsServerboundPacketImpl(nmsPacket), SignUpdatePacket { + override val position get() = nmsPacket.pos.toBukkit() + override val lines: Array get() = nmsPacket.lines + override val isFrontText get() = nmsPacket.isFrontText + + override fun getLine(line: Int): String { + require(line in 1..4) { "Line must be between 1 and 4" } + return lines[line - 1] + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1GlowingPacketListener.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1GlowingPacketListener.kt new file mode 100644 index 000000000..44c3e8c5f --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1GlowingPacketListener.kt @@ -0,0 +1,100 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.packet.listener + +import com.github.benmanes.caffeine.cache.Caffeine +import com.sksamuel.aedile.core.expireAfterWrite +import dev.slne.surf.api.core.util.mutableObjectListOf +import dev.slne.surf.api.core.util.toMutableObjectList +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.packet.listener.listener.PacketListener +import dev.slne.surf.api.paper.packet.listener.listener.annotation.ClientboundListener +import dev.slne.surf.api.paper.server.impl.glow.SurfGlowingApiImpl +import dev.slne.surf.api.paper.server.nms.v26_1.reflection.V26_1Reflection +import glm_.or +import net.minecraft.network.protocol.Packet +import net.minecraft.network.protocol.game.ClientboundBundlePacket +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket +import net.minecraft.network.syncher.SynchedEntityData.DataValue +import org.bukkit.entity.Player +import kotlin.time.Duration.Companion.seconds + +@OptIn(NmsUseWithCaution::class) +object V26_1GlowingPacketListener : PacketListener { + + val ignoreCache = Caffeine.newBuilder() + .weakKeys() + .expireAfterWrite(5.seconds) + .build, Unit>() + + fun ignorePacket(packet: Packet<*>) { + ignoreCache.put(packet, Unit) + } + + @ClientboundListener + fun onBundlePacket(packet: ClientboundBundlePacket, player: Player): ClientboundBundlePacket { + val bundles = packet.subPackets().toMutableObjectList() + bundles.replaceAll { subPacket -> + if (subPacket is ClientboundSetEntityDataPacket) { + updatePacketIfNeeded(subPacket, player) + } else { + subPacket + } + } + + return ClientboundBundlePacket(bundles) + } + + @ClientboundListener + fun onSetEntityDataPacket( + packet: ClientboundSetEntityDataPacket, + player: Player, + ): ClientboundSetEntityDataPacket { + return updatePacketIfNeeded(packet, player) + } + + private fun updatePacketIfNeeded( + packet: ClientboundSetEntityDataPacket, + player: Player + ): ClientboundSetEntityDataPacket { + // Ignore packets that we don't care about + if (ignoreCache.asMap().remove(packet) != null) { + return packet + } + + val playerData = SurfGlowingApiImpl.getEntityPlayerData(player) ?: return packet + val glowingData = playerData.entities.get(packet.id) ?: return packet + val incoming = packet.packedItems + var flagsFound = false + var edited = false + val newItems = mutableObjectListOf>(incoming.size + 1) + val dataFlagsShared = V26_1Reflection.ENTITY_PROXY.getDataFlagsSharedId() + val dataFlagsSharedId = dataFlagsShared.id + + for (dataValue in incoming) { + if (dataValue.id == dataFlagsSharedId) { + flagsFound = true + val current = dataValue.value as Byte + glowingData.otherFlags = current + val withGlow: Byte = current or SurfGlowingApiImpl.glowingFlag + + if (withGlow != current) { + edited = true + newItems.add(DataValue(dataFlagsSharedId, dataFlagsShared.serializer, withGlow)) + } else { + newItems.add(dataValue) + } + } else { + newItems.add(dataValue) + } + } + + if (!edited && !flagsFound) { + val withGlow = glowingData.otherFlags or SurfGlowingApiImpl.glowingFlag + if (withGlow != 0.toByte()) { + edited = true + newItems.add(DataValue(dataFlagsSharedId, dataFlagsShared.serializer, withGlow)) + } + } + + return if (edited) ClientboundSetEntityDataPacket(packet.id, newItems) else packet + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/lore/V26_1PacketLoreListener.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/lore/V26_1PacketLoreListener.kt new file mode 100644 index 000000000..d0211e19b --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/lore/V26_1PacketLoreListener.kt @@ -0,0 +1,388 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.packet.lore + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.packet.listener.listener.PacketListener +import dev.slne.surf.api.paper.packet.listener.listener.annotation.ClientboundListener +import dev.slne.surf.api.paper.packet.listener.listener.annotation.ServerboundListener +import dev.slne.surf.api.paper.packet.lore.SurfPaperPacketLoreHandler +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toBukkit +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toNms +import dev.slne.surf.api.paper.util.namespacedKey +import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap +import it.unimi.dsi.fastutil.objects.ObjectArrayList +import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet +import it.unimi.dsi.fastutil.objects.ObjectLists +import net.kyori.adventure.text.format.TextDecoration +import net.minecraft.core.component.DataComponents +import net.minecraft.network.protocol.game.* +import net.minecraft.server.level.ServerPlayer +import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.component.CustomData +import net.minecraft.world.item.component.ItemLore +import org.bukkit.NamespacedKey +import org.bukkit.plugin.Plugin +import net.minecraft.network.chat.Component as MinecraftComponent + +/** + * PacketLoreListener is a class that implements PacketListenerAbstract and is responsible for + * handling the modification of lore on item stacks in packet events. + */ +@OptIn(NmsUseWithCaution::class) +object V26_1PacketLoreListener : PacketListener { + private val globalHandlersByPlugin = + Object2ObjectLinkedOpenHashMap>() + + private val keyedHandlersByPlugin = + Object2ObjectLinkedOpenHashMap>() + + @Volatile + private var keyedHandlersSnapshot: Map = emptyMap() + + @Volatile + private var globalHandlersSnapshot: Array = emptyArray() + + private val ORIGINAL_LORE_KEY = namespacedKey("original_lore") + private val ORIGINAL_LORE_KEY_STRING = ORIGINAL_LORE_KEY.asString() + + private fun hasAnyHandlers(): Boolean = + keyedHandlersSnapshot.isNotEmpty() || globalHandlersSnapshot.isNotEmpty() + + @ServerboundListener + fun onPacketReceive(event: ServerboundSetCreativeModeSlotPacket) { + makeCleanItemStack(event.itemStack()) + } + + @ClientboundListener + fun onWindowItem(event: ClientboundContainerSetContentPacket): ClientboundContainerSetContentPacket { + if (!hasAnyHandlers()) return event + + val sourceItems = event.items + val updatedItems = ObjectArrayList(sourceItems.size) + + var changed = false + + for (i in sourceItems.indices) { + val original = sourceItems[i] + val updated = makeUpdatedItemStack(original) + + if (updated !== original) { + changed = true + } + + updatedItems.add(updated) + } + + val originalCarried = event.carriedItem() + val updatedCarried = makeUpdatedItemStack(originalCarried) + + if (updatedCarried !== originalCarried) { + changed = true + } + + if (!changed) { + return event + } + + return ClientboundContainerSetContentPacket( + event.containerId(), + event.stateId(), + updatedItems, + updatedCarried + ) + } + + @ClientboundListener + fun onSetSlotPacket(event: ClientboundContainerSetSlotPacket): ClientboundContainerSetSlotPacket { + val original = event.item + val updated = makeUpdatedItemStack(original) + + if (updated === original) { + return event + } + + return ClientboundContainerSetSlotPacket( + event.containerId, + event.stateId, + event.slot, + updated + ) + } + + @ClientboundListener + fun onSetPlayerInventoryPacket(event: ClientboundSetPlayerInventoryPacket): ClientboundSetPlayerInventoryPacket { + val original = event.contents + val updated = makeUpdatedItemStack(original) + + if (updated === original) { + return event + } + + return ClientboundSetPlayerInventoryPacket( + event.slot(), + updated + ) + } + + @ServerboundListener + fun onContainerClickPacket( + event: ServerboundContainerClickPacket, + player: ServerPlayer + ): ServerboundContainerClickPacket { + if (!hasAnyHandlers()) return event + + val container = player.containerMenu + val currentStateId = container.stateId + + val brokenStateId = if (event.stateId() == currentStateId) { + currentStateId - 1 + } else { + event.stateId() + } + + if (brokenStateId == event.stateId()) return event + + return ServerboundContainerClickPacket( + event.containerId(), + brokenStateId, + event.slotNum(), + event.buttonNum(), + event.containerInput(), + event.changedSlots(), + event.carriedItem() + ) + } + + @ClientboundListener + fun onSetCursorItemPacket(event: ClientboundSetCursorItemPacket): ClientboundSetCursorItemPacket { + val original = event.contents + val updated = makeUpdatedItemStack(original) + + if (updated === original) { + return event + } + + return ClientboundSetCursorItemPacket(updated) + } + + /** + * Returns the original item if: + * - item is empty + * - no handlers exist + * - no keyed handler matches and no global handler exists + * - handlers run but lore result is identical + * + * Only copies the stack if at least one handler will actually run. + */ + private fun makeUpdatedItemStack( + original: ItemStack, + ): ItemStack { + if (original.isEmpty) return original + + // One volatile read + val keyedSnapshot = keyedHandlersSnapshot + val globalSnapshot = globalHandlersSnapshot + + if (keyedSnapshot.isEmpty() && globalSnapshot.isEmpty()) { + return original + } + + /* + * We need Bukkit PDC for the current handler API, but only when there + * are keyed handlers to consider. The original mirror is used to cheaply + * determine whether any keyed handlers actually match. + */ + val matchingKeyedHandlers = if (keyedSnapshot.isNotEmpty()) { + val originalBukkitStack = original.asBukkitMirror() + val originalPdc = originalBukkitStack.persistentDataContainer + resolveMatchingKeyedHandlers( + originalPdc.keys, + keyedSnapshot + ) + } else { + ObjectLists.emptyList() + } + + if (matchingKeyedHandlers.isEmpty() && globalSnapshot.isEmpty()) { + return original + } + + /* + * From here on, we know that at least one handler will run. + * Only now create a copy. + */ + val item = original.copy() + val bukkitStack = item.asBukkitMirror() + val pdc = bukkitStack.persistentDataContainer + + val originalLore = item.getOrDefault(DataComponents.LORE, ItemLore.EMPTY) + val originalLines = originalLore.lines + + val mutableLore = originalLines.mapTo( + ObjectArrayList(originalLines.size) + ) { it.toBukkit() } + + for (i in matchingKeyedHandlers.indices) { + matchingKeyedHandlers[i].handleLore(mutableLore, pdc, bukkitStack) + } + + for (i in globalSnapshot.indices) { + globalSnapshot[i].handleLore(mutableLore, pdc, bukkitStack) + } + + val updatedLines = ObjectArrayList(mutableLore.size) + for (i in mutableLore.indices) { + val line = + mutableLore[i].decorationIfAbsent(TextDecoration.ITALIC, TextDecoration.State.FALSE) + updatedLines.add(line.toNms()) + } + + val updatedLore = ItemLore(updatedLines) + + if (updatedLore == originalLore) { + return original + } + + item.set(DataComponents.LORE, updatedLore) + CustomData.update(DataComponents.CUSTOM_DATA, item) { tag -> + if (!tag.contains(ORIGINAL_LORE_KEY_STRING)) { + tag.store(ORIGINAL_LORE_KEY_STRING, ItemLore.CODEC, originalLore) + } + } + + return item + } + + private fun makeCleanItemStack( + stack: ItemStack, + ): ItemStack { + if (stack.isEmpty) { + return stack + } + + val customData = stack.get(DataComponents.CUSTOM_DATA) ?: return stack + if (!customData.contains(ORIGINAL_LORE_KEY_STRING)) { + return stack + } + + CustomData.update(DataComponents.CUSTOM_DATA, stack) { tag -> + val originalLore = tag.read(ORIGINAL_LORE_KEY_STRING, ItemLore.CODEC) + originalLore.ifPresent { lore -> + stack.set(DataComponents.LORE, lore) + tag.remove(ORIGINAL_LORE_KEY_STRING) + } + } + + return stack + } + + private fun resolveMatchingKeyedHandlers( + itemKeys: Set, + keyedSnapshot: Map, + ): List { + if (itemKeys.isEmpty() || keyedSnapshot.isEmpty()) { + return emptyList() + } + + var result: ObjectArrayList? = null + for (key in itemKeys) { + val handler = keyedSnapshot[key] ?: continue + + if (result == null) { + result = ObjectArrayList(2) + } + + result.add(handler) + } + + return result ?: emptyList() + } + + fun register(plugin: Plugin, identifier: NamespacedKey, listener: SurfPaperPacketLoreHandler) { + synchronized(this) { + check(!keyedHandlersSnapshot.containsKey(identifier)) { + "A PacketLore handler for $identifier is already registered!" + } + + val handlers = + keyedHandlersByPlugin.computeIfAbsent(plugin) { Object2ObjectLinkedOpenHashMap() } + + val previous = handlers.putIfAbsent(identifier, listener) + check(previous == null) { + "A PacketLore handler for $identifier is already registered for plugin ${plugin.name}!" + } + + val newSnapshot = Object2ObjectLinkedOpenHashMap(keyedHandlersSnapshot) + newSnapshot[identifier] = listener + keyedHandlersSnapshot = newSnapshot + } + } + + fun register(plugin: Plugin, listener: SurfPaperPacketLoreHandler) { + synchronized(this) { + val handlers = + globalHandlersByPlugin.computeIfAbsent(plugin) { ObjectLinkedOpenHashSet() } + if (handlers.add(listener)) { + rebuildGlobalHandlersSnapshot() + } else { + error("A PacketLore handler identical to the provided one (${listener.javaClass.name}) is already registered for plugin ${plugin.name}!") + } + } + } + + fun unregister(identifier: NamespacedKey) { + synchronized(this) { + if (!keyedHandlersSnapshot.containsKey(identifier)) { + return + } + + var emptyPlugin: Plugin? = null + + for ((plugin, handlers) in keyedHandlersByPlugin) { + if (handlers.remove(identifier) != null) { + if (handlers.isEmpty()) { + emptyPlugin = plugin + } + break + } + } + + if (emptyPlugin != null) { + keyedHandlersByPlugin.remove(emptyPlugin) + } + + val newSnapshot = Object2ObjectLinkedOpenHashMap(keyedHandlersSnapshot) + newSnapshot.remove(identifier) + keyedHandlersSnapshot = newSnapshot + } + } + + fun unregister(plugin: Plugin) { + synchronized(this) { + val removedGlobal = globalHandlersByPlugin.remove(plugin) != null + if (removedGlobal) { + rebuildGlobalHandlersSnapshot() + } + + val removedKeyed = keyedHandlersByPlugin.remove(plugin) + if (removedKeyed != null) { + val newSnapshot = Object2ObjectLinkedOpenHashMap(keyedHandlersSnapshot) + for (identifier in removedKeyed.keys) { + newSnapshot.remove(identifier) + } + keyedHandlersSnapshot = newSnapshot + } + } + } + + private fun rebuildGlobalHandlersSnapshot() { + val snapshot = ObjectArrayList() + + globalHandlersByPlugin.object2ObjectEntrySet().fastForEach { (plugin, handlers) -> + if (plugin.isEnabled) { + snapshot.addAll(handlers) + } + } + + globalHandlersSnapshot = snapshot.toTypedArray() + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1EntityProxy.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1EntityProxy.kt new file mode 100644 index 000000000..8dff2b153 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1EntityProxy.kt @@ -0,0 +1,23 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.reflection + +import net.minecraft.network.syncher.EntityDataAccessor +import net.minecraft.world.entity.Entity +import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldGetter +import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies +import xyz.jpenilla.reflectionremapper.proxy.annotation.Static + +@Proxies(Entity::class) +interface V26_1EntityProxy { + + @FieldGetter("FLAG_GLOWING") + @Static + fun getFlagGlowing(): Int + + @FieldGetter("FLAG_INVISIBLE") + @Static + fun getFlagInvisible(): Int + + @FieldGetter("DATA_SHARED_FLAGS_ID") + @Static + fun getDataFlagsSharedId(): EntityDataAccessor +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1Reflection.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1Reflection.kt new file mode 100644 index 000000000..fb6e60e5d --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1Reflection.kt @@ -0,0 +1,37 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.reflection + +import dev.slne.surf.api.core.reflection.SurfReflection +import dev.slne.surf.api.core.reflection.createProxy +import dev.slne.surf.api.paper.util.reflectionProxy +import xyz.jpenilla.reflectionremapper.ReflectionRemapper +import xyz.jpenilla.reflectionremapper.proxy.ReflectionProxyFactory + +object V26_1Reflection { + lateinit var SERVER_STATS_COUNTER_PROXY: V26_1ServerStatsCounterProxy + private set + lateinit var ENTITY_PROXY: V26_1EntityProxy + private set + lateinit var SERVER_CONNECTION_LISTENER_PROXY: V26_1ServerConnectionListenerProxy + private set + lateinit var VANILLA_ARGUMENT_PROVIDER_IMPL_PROXY: V26_1VanillaArgumentProviderImplProxy + private set + lateinit var VANILLA_ARGUMENT_PROVIDER_PROXY: V26_1VanillaArgumentProviderProxy + private set + + fun initialize() { + val remapper = ReflectionRemapper.forReobfMappingsInPaperJar() + val proxyFactory = + ReflectionProxyFactory.create(remapper, V26_1Reflection::class.java.classLoader) + + SERVER_STATS_COUNTER_PROXY = proxyFactory.reflectionProxy() + ENTITY_PROXY = proxyFactory.reflectionProxy() + SERVER_CONNECTION_LISTENER_PROXY = + proxyFactory.reflectionProxy() + VANILLA_ARGUMENT_PROVIDER_IMPL_PROXY = + SurfReflection.createProxy() + VANILLA_ARGUMENT_PROVIDER_PROXY = SurfReflection.createProxy() + + // gc the remapper + System.gc() + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ServerConnectionListenerProxy.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ServerConnectionListenerProxy.kt new file mode 100644 index 000000000..aa667e46c --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ServerConnectionListenerProxy.kt @@ -0,0 +1,12 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.reflection + +import io.netty.channel.ChannelFuture +import net.minecraft.server.network.ServerConnectionListener +import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldGetter +import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies + +@Proxies(ServerConnectionListener::class) +interface V26_1ServerConnectionListenerProxy { + @FieldGetter("channels") + fun getChannels(instance: ServerConnectionListener): List +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ServerStatsCounterProxy.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ServerStatsCounterProxy.kt new file mode 100644 index 000000000..991e4e692 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ServerStatsCounterProxy.kt @@ -0,0 +1,20 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.reflection + +import com.google.gson.Gson +import com.google.gson.JsonElement +import net.minecraft.stats.ServerStatsCounter +import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldGetter +import xyz.jpenilla.reflectionremapper.proxy.annotation.MethodName +import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies +import xyz.jpenilla.reflectionremapper.proxy.annotation.Static + +@Proxies(ServerStatsCounter::class) +interface V26_1ServerStatsCounterProxy { + + @MethodName("toJson") + fun toJson(statsCounter: ServerStatsCounter): JsonElement + + @FieldGetter("GSON") + @Static + fun getGson(): Gson +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1VanillaArgumentProviderImplProxy.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1VanillaArgumentProviderImplProxy.kt new file mode 100644 index 000000000..40258532f --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1VanillaArgumentProviderImplProxy.kt @@ -0,0 +1,15 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.reflection + +import com.mojang.brigadier.arguments.ArgumentType +import com.mojang.brigadier.exceptions.CommandSyntaxException +import dev.slne.surf.api.core.reflection.Name +import dev.slne.surf.api.core.reflection.SurfProxy +import io.papermc.paper.command.brigadier.argument.VanillaArgumentProviderImpl + +@SurfProxy(VanillaArgumentProviderImpl::class) +interface V26_1VanillaArgumentProviderImplProxy { + + @Name("wrap") + @Throws(CommandSyntaxException::class) + fun wrap(instance: Any, base: Any, converter: Any): ArgumentType<*> +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1VanillaArgumentProviderProxy.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1VanillaArgumentProviderProxy.kt new file mode 100644 index 000000000..e30dee3c9 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1VanillaArgumentProviderProxy.kt @@ -0,0 +1,14 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.reflection + +import dev.slne.surf.api.core.reflection.Name +import dev.slne.surf.api.core.reflection.Static +import dev.slne.surf.api.core.reflection.SurfProxy + + +@SurfProxy(qualifiedName = "io.papermc.paper.command.brigadier.argument.VanillaArgumentProvider") +interface V26_1VanillaArgumentProviderProxy { + + @Static + @Name("provider") + fun provider(): Any +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/region/V26_1TickThreadGuard.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/region/V26_1TickThreadGuard.kt new file mode 100644 index 000000000..bbf42b7b1 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/region/V26_1TickThreadGuard.kt @@ -0,0 +1,65 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.region + +import ca.spottedleaf.moonrise.common.util.TickThread +import dev.slne.surf.api.paper.region.TickThreadGuard +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toNms +import dev.slne.surf.api.paper.util.chunkX +import dev.slne.surf.api.paper.util.chunkZ +import io.papermc.paper.math.Position +import net.minecraft.core.BlockPos +import net.minecraft.world.phys.AABB +import org.bukkit.World +import org.bukkit.entity.Entity +import org.bukkit.util.BoundingBox + +@Suppress("UnstableApiUsage") +class V26_1TickThreadGuard : TickThreadGuard { + + override fun ensureTickThread(world: World, pos: Position, reason: String) { + TickThread.ensureTickThread(world.toNms(), pos.chunkX, pos.chunkZ, reason) + } + + override fun ensureTickThread( + world: World, + pos: Position, + blockRadius: Int, + reason: String + ) { + TickThread.ensureTickThread( + world.toNms(), + BlockPos(pos.blockX(), pos.blockY(), pos.blockZ()), + blockRadius, + reason + ) + } + + override fun ensureTickThread( + world: World, + chunkX: Int, + chunkZ: Int, + reason: String + ) { + TickThread.ensureTickThread(world.toNms(), chunkX, chunkZ, reason) + } + + override fun ensureTickThread(entity: Entity, reason: String) { + TickThread.ensureTickThread(entity.toNms(), reason) + } + + override fun ensureTickThread(world: World, box: BoundingBox, reason: String) { + TickThread.ensureTickThread( + world.toNms(), + AABB(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ), + reason + ) + } + + override fun ensureTickThread( + world: World, + blockX: Double, + blockZ: Double, + reason: String + ) { + TickThread.ensureTickThread(world.toNms(), blockX, blockZ, reason) + } +} From 064a344809441a7ea04432af8522b06caa57a4d0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Apr 2026 20:33:19 +0000 Subject: [PATCH 03/34] feat: add multiversion NMS support architecture for MC 1.21.11 + 26.1 - Create surf-api-paper-nms-common module with NmsVersion, NmsProvider, NmsPacketBridgeHandler - Create surf-api-paper-nms-v26-1 module with all 26.1 NMS implementations - Create surf-api-paper-nms-v1-21-11 module with skeleton NmsProvider (TODO implementations) - Add proxy bridge implementations in surf-api-paper-server delegating to NmsProvider - Register new modules in settings.gradle.kts Agent-Logs-Url: https://github.com/SLNE-Development/surf-api/sessions/3048aef9-7f6a-422b-82bf-1b0453b10e0d Co-authored-by: TheBjoRedCraft <143264463+TheBjoRedCraft@users.noreply.github.com> --- .../nms/common/NmsPacketBridgeHandler.kt | 40 +++++ .../surf/api/paper/nms/common/NmsProvider.kt | 15 ++ .../nms/v1_21_11/V1_21_11NmsProvider.kt | 94 ++++++++++ .../nms/v26_1/V26_1NmsPacketBridgeHandler.kt | 28 +++ .../server/nms/v26_1/V26_1NmsProvider.kt | 14 ++ .../nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt | 170 ++++++++++++++++++ .../paper/server/proxy/SurfGlowingApiProxy.kt | 12 ++ .../proxy/SurfPaperNmsBlockPacketsProxy.kt | 14 ++ .../server/proxy/SurfPaperNmsBridgeProxy.kt | 14 ++ ...PaperNmsCommandArgumentTypesBridgeProxy.kt | 14 ++ .../proxy/SurfPaperNmsCommonBridgeProxy.kt | 21 +++ .../proxy/SurfPaperNmsEntityBridgeProxy.kt | 14 ++ .../proxy/SurfPaperNmsGlowingBridgeProxy.kt | 14 ++ .../proxy/SurfPaperNmsItemBridgeProxy.kt | 14 ++ .../proxy/SurfPaperNmsLootTableBridgeProxy.kt | 14 ++ .../proxy/SurfPaperNmsNbtBridgeProxy.kt | 14 ++ .../proxy/SurfPaperNmsPacketBridgesProxy.kt | 14 ++ .../SurfPaperNmsPlayerChatPacketsProxy.kt | 14 ++ .../proxy/SurfPaperNmsPlayerPacketsProxy.kt | 14 ++ .../SurfPaperNmsPlayerToastPacketsProxy.kt | 14 ++ .../proxy/SurfPaperNmsSpawnPacketsProxy.kt | 14 ++ .../proxy/SurfPaperNmsStatsBridgeProxy.kt | 14 ++ .../server/proxy/TickThreadGuardProxy.kt | 12 ++ 23 files changed, 602 insertions(+) create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsPacketBridgeHandler.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsPacketBridgeHandler.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt create mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfGlowingApiProxy.kt create mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsBlockPacketsProxy.kt create mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsBridgeProxy.kt create mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsCommandArgumentTypesBridgeProxy.kt create mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsCommonBridgeProxy.kt create mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsEntityBridgeProxy.kt create mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsGlowingBridgeProxy.kt create mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsItemBridgeProxy.kt create mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsLootTableBridgeProxy.kt create mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsNbtBridgeProxy.kt create mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsPacketBridgesProxy.kt create mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsPlayerChatPacketsProxy.kt create mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsPlayerPacketsProxy.kt create mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsPlayerToastPacketsProxy.kt create mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsSpawnPacketsProxy.kt create mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsStatsBridgeProxy.kt create mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/TickThreadGuardProxy.kt diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsPacketBridgeHandler.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsPacketBridgeHandler.kt new file mode 100644 index 000000000..033cc367f --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsPacketBridgeHandler.kt @@ -0,0 +1,40 @@ +package dev.slne.surf.api.paper.nms.common + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.listener.packets.NmsPacket +import dev.slne.surf.api.paper.nms.listener.packets.clientbound.NmsClientboundPacket +import dev.slne.surf.api.paper.nms.listener.packets.serverbound.NmsServerboundPacket + +/** + * Handles wrapping/unwrapping of NMS packets for the channel injector. + * + * This interface bridges the gap between raw NMS packet objects (passed as [Any]) + * and the API-level [NmsPacket] wrappers, allowing version-specific packet + * handling without the channel injector needing to know about specific NMS types. + */ +@NmsUseWithCaution +interface NmsPacketBridgeHandler { + /** + * Wraps a raw NMS serverbound packet into an API [NmsServerboundPacket]. + * + * @param nmsPacket the raw NMS packet object + * @return the API wrapper, or `null` if no wrapper is available for this packet type + */ + fun wrapServerboundPacket(nmsPacket: Any): NmsServerboundPacket? + + /** + * Wraps a raw NMS clientbound packet into an API [NmsClientboundPacket]. + * + * @param nmsPacket the raw NMS packet object + * @return the API wrapper, or `null` if no wrapper is available for this packet type + */ + fun wrapClientboundPacket(nmsPacket: Any): NmsClientboundPacket? + + /** + * Extracts the underlying NMS packet from an API [NmsPacket] wrapper. + * + * @param apiPacket the API packet wrapper + * @return the raw NMS packet object + */ + fun unwrapPacket(apiPacket: NmsPacket): Any +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt index 3acd6f38c..c248709d0 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt @@ -1,5 +1,6 @@ package dev.slne.surf.api.paper.nms.common +import dev.slne.surf.api.paper.glow.SurfGlowingApi import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge import dev.slne.surf.api.paper.nms.bridges.* import dev.slne.surf.api.paper.nms.bridges.packets.SurfPaperNmsPacketBridges @@ -44,6 +45,20 @@ interface NmsProvider { fun createPlayerToastPackets(): SurfPaperNmsPlayerToastPackets fun createTickThreadGuard(): TickThreadGuard + // ==================== Packet Bridge Handler ==================== // + + /** + * Creates the packet bridge handler for wrapping/unwrapping NMS packets. + */ + fun createPacketBridgeHandler(): NmsPacketBridgeHandler + + // ==================== Glowing API ==================== // + + /** + * Creates the version-specific glowing API implementation. + */ + fun createGlowingApi(): SurfGlowingApi + // ==================== Packet Listeners ==================== // /** diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt new file mode 100644 index 000000000..448651c5d --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt @@ -0,0 +1,94 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11 + +import com.google.auto.service.AutoService +import dev.slne.surf.api.paper.glow.SurfGlowingApi +import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge +import dev.slne.surf.api.paper.nms.bridges.* +import dev.slne.surf.api.paper.nms.bridges.packets.SurfPaperNmsPacketBridges +import dev.slne.surf.api.paper.nms.bridges.packets.block.SurfPaperNmsBlockPackets +import dev.slne.surf.api.paper.nms.bridges.packets.entity.SurfPaperNmsSpawnPackets +import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerChatPackets +import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerPackets +import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToastPackets +import dev.slne.surf.api.paper.nms.common.NmsPacketBridgeHandler +import dev.slne.surf.api.paper.nms.common.NmsProvider +import dev.slne.surf.api.paper.nms.common.NmsVersion +import dev.slne.surf.api.paper.packet.listener.listener.PacketListener +import dev.slne.surf.api.paper.region.TickThreadGuard + +/** + * NMS provider for Minecraft 1.21.11. + * + * TODO: Implement all methods with 1.21.11-specific NMS code. + * Each method should return an implementation adapted for the 1.21.11 NMS API. + * Use the V26_1 implementations as a reference and adapt for API differences. + */ +@AutoService(NmsProvider::class) +class V1_21_11NmsProvider : NmsProvider { + override val version: NmsVersion = NmsVersion.V1_21_11 + + override fun createNmsBridge(): SurfPaperNmsBridge = + TODO("Implement SurfPaperNmsBridge for 1.21.11") + + override fun createCommonBridge(): SurfPaperNmsCommonBridge = + TODO("Implement SurfPaperNmsCommonBridge for 1.21.11") + + override fun createEntityBridge(): SurfPaperNmsEntityBridge = + TODO("Implement SurfPaperNmsEntityBridge for 1.21.11") + + override fun createItemBridge(): SurfPaperNmsItemBridge = + TODO("Implement SurfPaperNmsItemBridge for 1.21.11") + + override fun createNbtBridge(): SurfPaperNmsNbtBridge = + TODO("Implement SurfPaperNmsNbtBridge for 1.21.11") + + override fun createGlowingBridge(): SurfPaperNmsGlowingBridge = + TODO("Implement SurfPaperNmsGlowingBridge for 1.21.11") + + override fun createStatsBridge(): SurfPaperNmsStatsBridge = + TODO("Implement SurfPaperNmsStatsBridge for 1.21.11") + + override fun createLootTableBridge(): SurfPaperNmsLootTableBridge = + TODO("Implement SurfPaperNmsLootTableBridge for 1.21.11") + + override fun createCommandArgumentTypesBridge(): SurfPaperNmsCommandArgumentTypesBridge = + TODO("Implement SurfPaperNmsCommandArgumentTypesBridge for 1.21.11") + + override fun createPacketBridges(): SurfPaperNmsPacketBridges = + TODO("Implement SurfPaperNmsPacketBridges for 1.21.11") + + override fun createBlockPackets(): SurfPaperNmsBlockPackets = + TODO("Implement SurfPaperNmsBlockPackets for 1.21.11") + + override fun createSpawnPackets(): SurfPaperNmsSpawnPackets = + TODO("Implement SurfPaperNmsSpawnPackets for 1.21.11") + + override fun createPlayerPackets(): SurfPaperNmsPlayerPackets = + TODO("Implement SurfPaperNmsPlayerPackets for 1.21.11") + + override fun createPlayerChatPackets(): SurfPaperNmsPlayerChatPackets = + TODO("Implement SurfPaperNmsPlayerChatPackets for 1.21.11") + + override fun createPlayerToastPackets(): SurfPaperNmsPlayerToastPackets = + TODO("Implement SurfPaperNmsPlayerToastPackets for 1.21.11") + + override fun createTickThreadGuard(): TickThreadGuard = + TODO("Implement TickThreadGuard for 1.21.11") + + override fun createPacketBridgeHandler(): NmsPacketBridgeHandler = + TODO("Implement NmsPacketBridgeHandler for 1.21.11") + + override fun createGlowingApi(): SurfGlowingApi = + TODO("Implement SurfGlowingApi for 1.21.11") + + override fun createPacketListeners(): List = + TODO("Implement packet listeners for 1.21.11") + + override fun initialize() { + TODO("Initialize 1.21.11 NMS resources") + } + + override fun shutdown() { + // No cleanup needed + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsPacketBridgeHandler.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsPacketBridgeHandler.kt new file mode 100644 index 000000000..892270ff0 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsPacketBridgeHandler.kt @@ -0,0 +1,28 @@ +package dev.slne.surf.api.paper.server.nms.v26_1 + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.common.NmsPacketBridgeHandler +import dev.slne.surf.api.paper.nms.listener.packets.NmsPacket +import dev.slne.surf.api.paper.nms.listener.packets.clientbound.NmsClientboundPacket +import dev.slne.surf.api.paper.nms.listener.packets.serverbound.NmsServerboundPacket +import dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.V26_1NmsPacketImpl +import dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.V26_1PacketRegistry +import net.minecraft.network.protocol.Packet + +@NmsUseWithCaution +class V26_1NmsPacketBridgeHandler : NmsPacketBridgeHandler { + + @Suppress("UNCHECKED_CAST") + override fun wrapServerboundPacket(nmsPacket: Any): NmsServerboundPacket? { + return V26_1PacketRegistry.createServerboundPacketOrNull(nmsPacket as Packet<*>) + } + + @Suppress("UNCHECKED_CAST") + override fun wrapClientboundPacket(nmsPacket: Any): NmsClientboundPacket? { + return V26_1PacketRegistry.createClientboundPacketOrNull(nmsPacket as Packet<*>) + } + + override fun unwrapPacket(apiPacket: NmsPacket): Any { + return V26_1NmsPacketImpl.getFromApi(apiPacket).nmsPacket + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt index cee1b46e7..9f910cdbc 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt @@ -1,6 +1,7 @@ package dev.slne.surf.api.paper.server.nms.v26_1 import com.google.auto.service.AutoService +import dev.slne.surf.api.paper.glow.SurfGlowingApi import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge import dev.slne.surf.api.paper.nms.bridges.* import dev.slne.surf.api.paper.nms.bridges.packets.SurfPaperNmsPacketBridges @@ -9,6 +10,7 @@ import dev.slne.surf.api.paper.nms.bridges.packets.entity.SurfPaperNmsSpawnPacke import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerChatPackets import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerPackets import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToastPackets +import dev.slne.surf.api.paper.nms.common.NmsPacketBridgeHandler import dev.slne.surf.api.paper.nms.common.NmsProvider import dev.slne.surf.api.paper.nms.common.NmsVersion import dev.slne.surf.api.paper.packet.listener.listener.PacketListener @@ -20,15 +22,19 @@ import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.entity.V26_1Surf import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.player.V26_1SurfPaperNmsPlayerChatPacketsImpl import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.player.V26_1SurfPaperNmsPlayerPacketsImpl import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.player.V26_1SurfPaperNmsPlayerToastPacketsImpl +import dev.slne.surf.api.paper.server.nms.v26_1.glow.V26_1SurfGlowingApiImpl import dev.slne.surf.api.paper.server.nms.v26_1.packet.listener.V26_1GlowingPacketListener import dev.slne.surf.api.paper.server.nms.v26_1.packet.lore.V26_1PacketLoreListener import dev.slne.surf.api.paper.server.nms.v26_1.reflection.V26_1Reflection import dev.slne.surf.api.paper.server.nms.v26_1.region.V26_1TickThreadGuard +import org.bukkit.plugin.java.JavaPlugin @AutoService(NmsProvider::class) class V26_1NmsProvider : NmsProvider { override val version: NmsVersion = NmsVersion.V26_1 + private var glowingApi: V26_1SurfGlowingApiImpl? = null + override fun createNmsBridge(): SurfPaperNmsBridge = V26_1SurfPaperNmsBridgeImpl() override fun createCommonBridge(): SurfPaperNmsCommonBridge = V26_1SurfPaperNmsCommonBridgeImpl() override fun createEntityBridge(): SurfPaperNmsEntityBridge = V26_1SurfPaperNmsEntityBridgeImpl() @@ -45,6 +51,14 @@ class V26_1NmsProvider : NmsProvider { override fun createPlayerChatPackets(): SurfPaperNmsPlayerChatPackets = V26_1SurfPaperNmsPlayerChatPacketsImpl() override fun createPlayerToastPackets(): SurfPaperNmsPlayerToastPackets = V26_1SurfPaperNmsPlayerToastPacketsImpl() override fun createTickThreadGuard(): TickThreadGuard = V26_1TickThreadGuard() + override fun createPacketBridgeHandler(): NmsPacketBridgeHandler = V26_1NmsPacketBridgeHandler() + + override fun createGlowingApi(): SurfGlowingApi { + val plugin = JavaPlugin.getProvidingPlugin(V26_1NmsProvider::class.java) as JavaPlugin + val api = V26_1SurfGlowingApiImpl(plugin) + glowingApi = api + return api + } override fun createPacketListeners(): List = listOf( V26_1PacketLoreListener, diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt new file mode 100644 index 000000000..7ec402f2c --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt @@ -0,0 +1,170 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.glow + +import com.github.shynixn.mccoroutine.folia.entityDispatcher +import com.github.shynixn.mccoroutine.folia.launch +import dev.slne.surf.api.paper.extensions.server +import dev.slne.surf.api.paper.glow.SurfGlowingApi +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation +import dev.slne.surf.api.paper.server.nms.v26_1.bridges.V26_1SurfPaperNmsGlowingBridgeImpl +import dev.slne.surf.api.paper.server.nms.v26_1.glow.block.V26_1BlockGlowingData +import dev.slne.surf.api.paper.server.nms.v26_1.glow.block.BlockPlayerData +import dev.slne.surf.api.paper.server.nms.v26_1.glow.entity.EntityGlowingData +import dev.slne.surf.api.paper.server.nms.v26_1.glow.entity.EntityPlayerData +import dev.slne.surf.api.paper.server.nms.v26_1.reflection.V26_1Reflection +import dev.slne.surf.api.paper.util.isChunkVisible +import io.papermc.paper.adventure.PaperAdventure +import net.kyori.adventure.text.format.NamedTextColor +import org.bukkit.Location +import org.bukkit.block.Block +import org.bukkit.entity.Entity +import org.bukkit.entity.Player +import org.bukkit.plugin.java.JavaPlugin +import java.util.* +import java.util.concurrent.ConcurrentHashMap + +@NmsUseWithCaution +class V26_1SurfGlowingApiImpl(private val plugin: JavaPlugin) : SurfGlowingApi { + + override fun makeGlowing( + target: Entity, + viewer: Player, + color: NamedTextColor?, + ) { + makeGlowing( + target.entityId, + teamIdFor(target), + viewer, + color, + V26_1SurfPaperNmsGlowingBridgeImpl.INSTANCE.getCurrentFlags(target) + ) + } + + override fun makeGlowing( + targetId: Int, + teamId: String, + viewer: Player, + color: NamedTextColor?, + otherFlags: Byte, + ) { + val nmsColor = color?.let { PaperAdventure.asVanilla(it) } + val uuid = viewer.uniqueId + val playerData = entityPlayerData.computeIfAbsent(uuid) { EntityPlayerData(uuid) } + val glowingData = playerData.entities.get(targetId) + val operation = PacketOperation.start() + + if (glowingData == null) { + val newData = EntityGlowingData( + playerData, + targetId, + teamId, + nmsColor, + otherFlags + ) + playerData.entities.put(targetId, newData) + + operation.add(newData.sendGlowingFlag(enabled = true, ignorePacket = true)) + if (nmsColor != null) { + operation.add(newData.sendTeamColor()) + } + operation.execute(viewer) + return + } + + if (nmsColor == glowingData.color) return + if (nmsColor == null) { + operation.add(glowingData.removeFromTeam()) + glowingData.color = null + } else { + glowingData.color = nmsColor + operation.add(glowingData.sendTeamColor()) + } + + operation.execute(viewer) + } + + override fun makeGlowing(block: Block, viewer: Player, color: NamedTextColor) { + makeGlowing(block.location, viewer, color) + } + + override fun makeGlowing(location: Location, viewer: Player, color: NamedTextColor) { + location.checkFinite() + val blockLocation = location.toBlockLocation() + val uuid = viewer.uniqueId + val playerData = blockPlayerData.getOrPut(uuid) { BlockPlayerData(uuid) } + val blockData = playerData.blocks[blockLocation] + + if (blockData == null) { + val newData = V26_1BlockGlowingData(playerData, blockLocation, color) + playerData.blocks[blockLocation] = newData + + plugin.launch(plugin.entityDispatcher(viewer)) { + if (viewer.isChunkVisible(blockLocation)) { + newData.spawn().execute(viewer) + } + } + } else { + blockData.color = color + blockData.updateColor() + } + } + + override fun removeGlowing(target: Entity, viewer: Player) { + removeGlowing(target.entityId, viewer) + } + + fun removeGlowing(targetId: Int, viewer: UUID) { + val player = server.getPlayer(viewer) + + if (player == null) { + entityPlayerData[viewer]?.entities?.remove(targetId) + } else { + removeGlowing(targetId, player) + } + } + + override fun removeGlowing(targetId: Int, viewer: Player) { + val playerData = entityPlayerData[viewer.uniqueId] ?: return + val glowingData = playerData.entities.remove(targetId) ?: return + val operation = glowingData.sendGlowingFlag(enabled = false) + glowingData.removeFromTeam() + operation.execute(viewer) + } + + override fun removeGlowing(block: Block, viewer: Player) { + removeGlowing(block.location, viewer) + } + + override fun removeGlowing(location: Location, viewer: Player) { + location.checkFinite() + val blockLocation = location.toBlockLocation() + val playerData = blockPlayerData[viewer.uniqueId] ?: return + val blockData = playerData.blocks.remove(blockLocation) ?: return + + blockData.remove() + if (playerData.blocks.isEmpty()) { + blockPlayerData.remove(viewer.uniqueId) + } + } + + private fun teamIdFor(entity: Entity) = (entity as? Player)?.name ?: entity.uniqueId.toString() + + companion object { + private val entityPlayerData = ConcurrentHashMap() + private val blockPlayerData = ConcurrentHashMap() + + val glowingFlag = 1 shl V26_1Reflection.ENTITY_PROXY.getFlagGlowing() + + fun getEntityPlayerData(player: Player): EntityPlayerData? = + entityPlayerData[player.uniqueId] + + fun getBlockPlayerData(player: Player): BlockPlayerData? = + blockPlayerData[player.uniqueId] + + fun removeAllGlowingOnQuit(player: Player) { + val uuid = player.uniqueId + V26_1TeamData.removeFromAll(uuid) + entityPlayerData.remove(uuid)?.entities?.clear() + blockPlayerData.remove(uuid)?.blocks?.clear() + } + } +} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfGlowingApiProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfGlowingApiProxy.kt new file mode 100644 index 000000000..2e9c78c64 --- /dev/null +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfGlowingApiProxy.kt @@ -0,0 +1,12 @@ +package dev.slne.surf.api.paper.server.proxy + +import com.google.auto.service.AutoService +import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.glow.SurfGlowingApi +import dev.slne.surf.api.paper.nms.common.NmsProvider + +@AutoService(SurfGlowingApi::class) +class SurfGlowingApiProxy : + SurfGlowingApi by NmsProvider.current.createGlowingApi() { + init { checkInstantiationByServiceLoader() } +} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsBlockPacketsProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsBlockPacketsProxy.kt new file mode 100644 index 000000000..7e45205cc --- /dev/null +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsBlockPacketsProxy.kt @@ -0,0 +1,14 @@ +package dev.slne.surf.api.paper.server.proxy + +import com.google.auto.service.AutoService +import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.block.SurfPaperNmsBlockPackets +import dev.slne.surf.api.paper.nms.common.NmsProvider + +@NmsUseWithCaution +@AutoService(SurfPaperNmsBlockPackets::class) +class SurfPaperNmsBlockPacketsProxy : + SurfPaperNmsBlockPackets by NmsProvider.current.createBlockPackets() { + init { checkInstantiationByServiceLoader() } +} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsBridgeProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsBridgeProxy.kt new file mode 100644 index 000000000..2fce4f127 --- /dev/null +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsBridgeProxy.kt @@ -0,0 +1,14 @@ +package dev.slne.surf.api.paper.server.proxy + +import com.google.auto.service.AutoService +import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge +import dev.slne.surf.api.paper.nms.common.NmsProvider + +@NmsUseWithCaution +@AutoService(SurfPaperNmsBridge::class) +class SurfPaperNmsBridgeProxy : + SurfPaperNmsBridge by NmsProvider.current.createNmsBridge() { + init { checkInstantiationByServiceLoader() } +} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsCommandArgumentTypesBridgeProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsCommandArgumentTypesBridgeProxy.kt new file mode 100644 index 000000000..82f95def6 --- /dev/null +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsCommandArgumentTypesBridgeProxy.kt @@ -0,0 +1,14 @@ +package dev.slne.surf.api.paper.server.proxy + +import com.google.auto.service.AutoService +import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsCommandArgumentTypesBridge +import dev.slne.surf.api.paper.nms.common.NmsProvider + +@NmsUseWithCaution +@AutoService(SurfPaperNmsCommandArgumentTypesBridge::class) +class SurfPaperNmsCommandArgumentTypesBridgeProxy : + SurfPaperNmsCommandArgumentTypesBridge by NmsProvider.current.createCommandArgumentTypesBridge() { + init { checkInstantiationByServiceLoader() } +} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsCommonBridgeProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsCommonBridgeProxy.kt new file mode 100644 index 000000000..5a2eb1e5a --- /dev/null +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsCommonBridgeProxy.kt @@ -0,0 +1,21 @@ +package dev.slne.surf.api.paper.server.proxy + +import com.google.auto.service.AutoService +import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsCommonBridge +import dev.slne.surf.api.paper.nms.common.NmsProvider + +/** + * Version-aware proxy for [SurfPaperNmsCommonBridge]. + * + * Loaded via ServiceLoader, delegates to the NMS provider for the current server version. + */ +@NmsUseWithCaution +@AutoService(SurfPaperNmsCommonBridge::class) +class SurfPaperNmsCommonBridgeProxy : + SurfPaperNmsCommonBridge by NmsProvider.current.createCommonBridge() { + init { + checkInstantiationByServiceLoader() + } +} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsEntityBridgeProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsEntityBridgeProxy.kt new file mode 100644 index 000000000..9b9d0d6a2 --- /dev/null +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsEntityBridgeProxy.kt @@ -0,0 +1,14 @@ +package dev.slne.surf.api.paper.server.proxy + +import com.google.auto.service.AutoService +import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsEntityBridge +import dev.slne.surf.api.paper.nms.common.NmsProvider + +@NmsUseWithCaution +@AutoService(SurfPaperNmsEntityBridge::class) +class SurfPaperNmsEntityBridgeProxy : + SurfPaperNmsEntityBridge by NmsProvider.current.createEntityBridge() { + init { checkInstantiationByServiceLoader() } +} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsGlowingBridgeProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsGlowingBridgeProxy.kt new file mode 100644 index 000000000..1ae176f93 --- /dev/null +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsGlowingBridgeProxy.kt @@ -0,0 +1,14 @@ +package dev.slne.surf.api.paper.server.proxy + +import com.google.auto.service.AutoService +import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsGlowingBridge +import dev.slne.surf.api.paper.nms.common.NmsProvider + +@NmsUseWithCaution +@AutoService(SurfPaperNmsGlowingBridge::class) +class SurfPaperNmsGlowingBridgeProxy : + SurfPaperNmsGlowingBridge by NmsProvider.current.createGlowingBridge() { + init { checkInstantiationByServiceLoader() } +} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsItemBridgeProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsItemBridgeProxy.kt new file mode 100644 index 000000000..efb5b2078 --- /dev/null +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsItemBridgeProxy.kt @@ -0,0 +1,14 @@ +package dev.slne.surf.api.paper.server.proxy + +import com.google.auto.service.AutoService +import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsItemBridge +import dev.slne.surf.api.paper.nms.common.NmsProvider + +@NmsUseWithCaution +@AutoService(SurfPaperNmsItemBridge::class) +class SurfPaperNmsItemBridgeProxy : + SurfPaperNmsItemBridge by NmsProvider.current.createItemBridge() { + init { checkInstantiationByServiceLoader() } +} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsLootTableBridgeProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsLootTableBridgeProxy.kt new file mode 100644 index 000000000..961457bc0 --- /dev/null +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsLootTableBridgeProxy.kt @@ -0,0 +1,14 @@ +package dev.slne.surf.api.paper.server.proxy + +import com.google.auto.service.AutoService +import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsLootTableBridge +import dev.slne.surf.api.paper.nms.common.NmsProvider + +@NmsUseWithCaution +@AutoService(SurfPaperNmsLootTableBridge::class) +class SurfPaperNmsLootTableBridgeProxy : + SurfPaperNmsLootTableBridge by NmsProvider.current.createLootTableBridge() { + init { checkInstantiationByServiceLoader() } +} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsNbtBridgeProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsNbtBridgeProxy.kt new file mode 100644 index 000000000..bd5023230 --- /dev/null +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsNbtBridgeProxy.kt @@ -0,0 +1,14 @@ +package dev.slne.surf.api.paper.server.proxy + +import com.google.auto.service.AutoService +import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsNbtBridge +import dev.slne.surf.api.paper.nms.common.NmsProvider + +@NmsUseWithCaution +@AutoService(SurfPaperNmsNbtBridge::class) +class SurfPaperNmsNbtBridgeProxy : + SurfPaperNmsNbtBridge by NmsProvider.current.createNbtBridge() { + init { checkInstantiationByServiceLoader() } +} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsPacketBridgesProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsPacketBridgesProxy.kt new file mode 100644 index 000000000..0d6c01e78 --- /dev/null +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsPacketBridgesProxy.kt @@ -0,0 +1,14 @@ +package dev.slne.surf.api.paper.server.proxy + +import com.google.auto.service.AutoService +import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.SurfPaperNmsPacketBridges +import dev.slne.surf.api.paper.nms.common.NmsProvider + +@NmsUseWithCaution +@AutoService(SurfPaperNmsPacketBridges::class) +class SurfPaperNmsPacketBridgesProxy : + SurfPaperNmsPacketBridges by NmsProvider.current.createPacketBridges() { + init { checkInstantiationByServiceLoader() } +} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsPlayerChatPacketsProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsPlayerChatPacketsProxy.kt new file mode 100644 index 000000000..ad892c22c --- /dev/null +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsPlayerChatPacketsProxy.kt @@ -0,0 +1,14 @@ +package dev.slne.surf.api.paper.server.proxy + +import com.google.auto.service.AutoService +import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerChatPackets +import dev.slne.surf.api.paper.nms.common.NmsProvider + +@NmsUseWithCaution +@AutoService(SurfPaperNmsPlayerChatPackets::class) +class SurfPaperNmsPlayerChatPacketsProxy : + SurfPaperNmsPlayerChatPackets by NmsProvider.current.createPlayerChatPackets() { + init { checkInstantiationByServiceLoader() } +} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsPlayerPacketsProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsPlayerPacketsProxy.kt new file mode 100644 index 000000000..317a3735c --- /dev/null +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsPlayerPacketsProxy.kt @@ -0,0 +1,14 @@ +package dev.slne.surf.api.paper.server.proxy + +import com.google.auto.service.AutoService +import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerPackets +import dev.slne.surf.api.paper.nms.common.NmsProvider + +@NmsUseWithCaution +@AutoService(SurfPaperNmsPlayerPackets::class) +class SurfPaperNmsPlayerPacketsProxy : + SurfPaperNmsPlayerPackets by NmsProvider.current.createPlayerPackets() { + init { checkInstantiationByServiceLoader() } +} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsPlayerToastPacketsProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsPlayerToastPacketsProxy.kt new file mode 100644 index 000000000..3a7bd170f --- /dev/null +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsPlayerToastPacketsProxy.kt @@ -0,0 +1,14 @@ +package dev.slne.surf.api.paper.server.proxy + +import com.google.auto.service.AutoService +import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToastPackets +import dev.slne.surf.api.paper.nms.common.NmsProvider + +@NmsUseWithCaution +@AutoService(SurfPaperNmsPlayerToastPackets::class) +class SurfPaperNmsPlayerToastPacketsProxy : + SurfPaperNmsPlayerToastPackets by NmsProvider.current.createPlayerToastPackets() { + init { checkInstantiationByServiceLoader() } +} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsSpawnPacketsProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsSpawnPacketsProxy.kt new file mode 100644 index 000000000..6dc97319b --- /dev/null +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsSpawnPacketsProxy.kt @@ -0,0 +1,14 @@ +package dev.slne.surf.api.paper.server.proxy + +import com.google.auto.service.AutoService +import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.entity.SurfPaperNmsSpawnPackets +import dev.slne.surf.api.paper.nms.common.NmsProvider + +@NmsUseWithCaution +@AutoService(SurfPaperNmsSpawnPackets::class) +class SurfPaperNmsSpawnPacketsProxy : + SurfPaperNmsSpawnPackets by NmsProvider.current.createSpawnPackets() { + init { checkInstantiationByServiceLoader() } +} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsStatsBridgeProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsStatsBridgeProxy.kt new file mode 100644 index 000000000..102da7226 --- /dev/null +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsStatsBridgeProxy.kt @@ -0,0 +1,14 @@ +package dev.slne.surf.api.paper.server.proxy + +import com.google.auto.service.AutoService +import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsStatsBridge +import dev.slne.surf.api.paper.nms.common.NmsProvider + +@NmsUseWithCaution +@AutoService(SurfPaperNmsStatsBridge::class) +class SurfPaperNmsStatsBridgeProxy : + SurfPaperNmsStatsBridge by NmsProvider.current.createStatsBridge() { + init { checkInstantiationByServiceLoader() } +} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/TickThreadGuardProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/TickThreadGuardProxy.kt new file mode 100644 index 000000000..8e88cf241 --- /dev/null +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/TickThreadGuardProxy.kt @@ -0,0 +1,12 @@ +package dev.slne.surf.api.paper.server.proxy + +import com.google.auto.service.AutoService +import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.common.NmsProvider +import dev.slne.surf.api.paper.region.TickThreadGuard + +@AutoService(TickThreadGuard::class) +class TickThreadGuardProxy : + TickThreadGuard by NmsProvider.current.createTickThreadGuard() { + init { checkInstantiationByServiceLoader() } +} From c9e05f7553179c76478b28249a4c351ce3b4f842 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Apr 2026 20:49:27 +0000 Subject: [PATCH 04/34] feat: wire multiversion NMS support through server module - Fix V26_1 files to use own data classes instead of server.impl references - Create EntityGlowingData, EntityPlayerData, BlockPlayerData in v26_1 glow packages - Update PlayerChannelInjector to use NmsPacketBridgeHandler - Update PacketApiLoader to use NmsProvider for packet listeners - Update PaperInstance to remove direct Reflection init (moved to NmsProvider.initialize()) - Add PacketLoreRegistry and GlowingLifecycleHandler interfaces - Update SurfPaperPacketApiImpl, PluginDisablePacketLoreListener, GlowingListener to use NmsProvider - Update V26_1NmsProvider and V1_21_11NmsProvider with new factory methods Agent-Logs-Url: https://github.com/SLNE-Development/surf-api/sessions/b4c8c86c-2741-4ab8-aae6-f9f6995c0e54 Co-authored-by: TheBjoRedCraft <143264463+TheBjoRedCraft@users.noreply.github.com> --- .../nms/common/GlowingLifecycleHandler.kt | 33 +++++++++ .../surf/api/paper/nms/common/NmsProvider.kt | 10 +++ .../paper/nms/common/PacketLoreRegistry.kt | 18 +++++ .../nms/v1_21_11/V1_21_11NmsProvider.kt | 8 ++ .../server/nms/v26_1/V26_1NmsProvider.kt | 6 ++ .../glow/V26_1GlowingLifecycleHandler.kt | 33 +++++++++ .../nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt | 2 + .../nms/v26_1/glow/block/BlockPlayerData.kt | 11 +++ .../v26_1/glow/block/V26_1BlockGlowingData.kt | 7 +- .../v26_1/glow/entity/EntityGlowingData.kt | 73 +++++++++++++++++++ .../nms/v26_1/glow/entity/EntityPlayerData.kt | 8 ++ .../listener/V26_1GlowingPacketListener.kt | 8 +- .../packet/lore/V26_1PacketLoreRegistry.kt | 24 ++++++ .../surf-api-paper-server/build.gradle.kts | 4 + .../surf/api/paper/server/PaperInstance.kt | 6 -- .../paper/server/impl/glow/GlowingListener.kt | 30 ++++---- .../impl/packet/SurfPaperPacketApiImpl.kt | 13 ++-- .../paper/server/packet/PacketApiLoader.kt | 26 +++++-- .../packet/listener/PlayerChannelInjector.kt | 15 ++-- .../lore/PluginDisablePacketLoreListener.kt | 4 +- 20 files changed, 293 insertions(+), 46 deletions(-) create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/GlowingLifecycleHandler.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/PacketLoreRegistry.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1GlowingLifecycleHandler.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/BlockPlayerData.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityGlowingData.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityPlayerData.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/lore/V26_1PacketLoreRegistry.kt diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/GlowingLifecycleHandler.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/GlowingLifecycleHandler.kt new file mode 100644 index 000000000..ac9cd476a --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/GlowingLifecycleHandler.kt @@ -0,0 +1,33 @@ +package dev.slne.surf.api.paper.nms.common + +import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation +import org.bukkit.entity.Player + +/** + * Version-agnostic interface for glowing API lifecycle operations. + * + * Provides the operations needed by the GlowingListener event handler + * without depending on version-specific implementations. + */ +interface GlowingLifecycleHandler { + /** + * Removes all glowing effects for a player (called on quit). + */ + fun removeAllGlowingOnQuit(player: Player) + + /** + * Gets block glow spawn operations for a chunk load event. + * + * @param player the player who loaded the chunk + * @param chunkX the chunk X coordinate + * @param chunkZ the chunk Z coordinate + * @param world the world of the chunk + * @return a [PacketOperation] to spawn the glowing blocks, or null if none + */ + fun getBlockGlowSpawnOperationForChunk( + player: Player, + chunkX: Int, + chunkZ: Int, + world: org.bukkit.World + ): PacketOperation? +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt index c248709d0..285af491f 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt @@ -52,6 +52,16 @@ interface NmsProvider { */ fun createPacketBridgeHandler(): NmsPacketBridgeHandler + /** + * Creates the packet lore registry for managing version-specific lore handlers. + */ + fun createPacketLoreRegistry(): PacketLoreRegistry + + /** + * Creates the glowing lifecycle handler for event-driven glowing management. + */ + fun createGlowingLifecycleHandler(): GlowingLifecycleHandler + // ==================== Glowing API ==================== // /** diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/PacketLoreRegistry.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/PacketLoreRegistry.kt new file mode 100644 index 000000000..691f1b7cb --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/PacketLoreRegistry.kt @@ -0,0 +1,18 @@ +package dev.slne.surf.api.paper.nms.common + +import dev.slne.surf.api.paper.packet.lore.SurfPaperPacketLoreHandler +import org.bukkit.NamespacedKey +import org.bukkit.plugin.Plugin + +/** + * Version-agnostic interface for managing packet lore handlers. + * + * Each version module provides an implementation that delegates to + * its version-specific packet lore listener. + */ +interface PacketLoreRegistry { + fun register(plugin: Plugin, identifier: NamespacedKey, listener: SurfPaperPacketLoreHandler) + fun register(plugin: Plugin, listener: SurfPaperPacketLoreHandler) + fun unregister(identifier: NamespacedKey) + fun unregister(plugin: Plugin) +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt index 448651c5d..6dce0bc4a 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt @@ -10,9 +10,11 @@ import dev.slne.surf.api.paper.nms.bridges.packets.entity.SurfPaperNmsSpawnPacke import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerChatPackets import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerPackets import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToastPackets +import dev.slne.surf.api.paper.nms.common.GlowingLifecycleHandler import dev.slne.surf.api.paper.nms.common.NmsPacketBridgeHandler import dev.slne.surf.api.paper.nms.common.NmsProvider import dev.slne.surf.api.paper.nms.common.NmsVersion +import dev.slne.surf.api.paper.nms.common.PacketLoreRegistry import dev.slne.surf.api.paper.packet.listener.listener.PacketListener import dev.slne.surf.api.paper.region.TickThreadGuard @@ -78,6 +80,12 @@ class V1_21_11NmsProvider : NmsProvider { override fun createPacketBridgeHandler(): NmsPacketBridgeHandler = TODO("Implement NmsPacketBridgeHandler for 1.21.11") + override fun createPacketLoreRegistry(): PacketLoreRegistry = + TODO("Implement PacketLoreRegistry for 1.21.11") + + override fun createGlowingLifecycleHandler(): GlowingLifecycleHandler = + TODO("Implement GlowingLifecycleHandler for 1.21.11") + override fun createGlowingApi(): SurfGlowingApi = TODO("Implement SurfGlowingApi for 1.21.11") diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt index 9f910cdbc..ba1ef7933 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt @@ -10,9 +10,11 @@ import dev.slne.surf.api.paper.nms.bridges.packets.entity.SurfPaperNmsSpawnPacke import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerChatPackets import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerPackets import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToastPackets +import dev.slne.surf.api.paper.nms.common.GlowingLifecycleHandler import dev.slne.surf.api.paper.nms.common.NmsPacketBridgeHandler import dev.slne.surf.api.paper.nms.common.NmsProvider import dev.slne.surf.api.paper.nms.common.NmsVersion +import dev.slne.surf.api.paper.nms.common.PacketLoreRegistry import dev.slne.surf.api.paper.packet.listener.listener.PacketListener import dev.slne.surf.api.paper.region.TickThreadGuard import dev.slne.surf.api.paper.server.nms.v26_1.bridges.* @@ -22,9 +24,11 @@ import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.entity.V26_1Surf import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.player.V26_1SurfPaperNmsPlayerChatPacketsImpl import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.player.V26_1SurfPaperNmsPlayerPacketsImpl import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.player.V26_1SurfPaperNmsPlayerToastPacketsImpl +import dev.slne.surf.api.paper.server.nms.v26_1.glow.V26_1GlowingLifecycleHandler import dev.slne.surf.api.paper.server.nms.v26_1.glow.V26_1SurfGlowingApiImpl import dev.slne.surf.api.paper.server.nms.v26_1.packet.listener.V26_1GlowingPacketListener import dev.slne.surf.api.paper.server.nms.v26_1.packet.lore.V26_1PacketLoreListener +import dev.slne.surf.api.paper.server.nms.v26_1.packet.lore.V26_1PacketLoreRegistry import dev.slne.surf.api.paper.server.nms.v26_1.reflection.V26_1Reflection import dev.slne.surf.api.paper.server.nms.v26_1.region.V26_1TickThreadGuard import org.bukkit.plugin.java.JavaPlugin @@ -52,6 +56,8 @@ class V26_1NmsProvider : NmsProvider { override fun createPlayerToastPackets(): SurfPaperNmsPlayerToastPackets = V26_1SurfPaperNmsPlayerToastPacketsImpl() override fun createTickThreadGuard(): TickThreadGuard = V26_1TickThreadGuard() override fun createPacketBridgeHandler(): NmsPacketBridgeHandler = V26_1NmsPacketBridgeHandler() + override fun createPacketLoreRegistry(): PacketLoreRegistry = V26_1PacketLoreRegistry() + override fun createGlowingLifecycleHandler(): GlowingLifecycleHandler = V26_1GlowingLifecycleHandler() override fun createGlowingApi(): SurfGlowingApi { val plugin = JavaPlugin.getProvidingPlugin(V26_1NmsProvider::class.java) as JavaPlugin diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1GlowingLifecycleHandler.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1GlowingLifecycleHandler.kt new file mode 100644 index 000000000..72f668b4e --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1GlowingLifecycleHandler.kt @@ -0,0 +1,33 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.glow + +import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation +import dev.slne.surf.api.paper.nms.common.GlowingLifecycleHandler +import dev.slne.surf.api.paper.util.chunkX +import dev.slne.surf.api.paper.util.chunkZ +import org.bukkit.World +import org.bukkit.entity.Player + +class V26_1GlowingLifecycleHandler : GlowingLifecycleHandler { + override fun removeAllGlowingOnQuit(player: Player) { + V26_1SurfGlowingApiImpl.removeAllGlowingOnQuit(player) + } + + override fun getBlockGlowSpawnOperationForChunk( + player: Player, + chunkX: Int, + chunkZ: Int, + world: World + ): PacketOperation? { + val playerData = V26_1SurfGlowingApiImpl.getBlockPlayerData(player) ?: return null + val blockDataList = playerData.blocks + if (blockDataList.isEmpty()) return null + + val spawnOperation = PacketOperation.start() + for ((loc, block) in blockDataList) { + if (loc.chunkX != chunkX || loc.chunkZ != chunkZ || loc.world != world) continue + spawnOperation.add(block.spawn()) + } + + return spawnOperation + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt index 7ec402f2c..ed9b248d1 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt @@ -149,6 +149,8 @@ class V26_1SurfGlowingApiImpl(private val plugin: JavaPlugin) : SurfGlowingApi { private fun teamIdFor(entity: Entity) = (entity as? Player)?.name ?: entity.uniqueId.toString() companion object { + val INSTANCE get() = SurfGlowingApi.INSTANCE as V26_1SurfGlowingApiImpl + private val entityPlayerData = ConcurrentHashMap() private val blockPlayerData = ConcurrentHashMap() diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/BlockPlayerData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/BlockPlayerData.kt new file mode 100644 index 000000000..9002cbddf --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/BlockPlayerData.kt @@ -0,0 +1,11 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.glow.block + +import dev.slne.surf.api.core.util.mutableObject2ObjectMapOf +import dev.slne.surf.api.paper.extensions.server +import org.bukkit.Location +import java.util.* + +class BlockPlayerData(val uuid: UUID) { + val blocks = mutableObject2ObjectMapOf() + val player get() = server.getPlayer(uuid) +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/V26_1BlockGlowingData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/V26_1BlockGlowingData.kt index 5ab0b9474..e7d3e29e3 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/V26_1BlockGlowingData.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/V26_1BlockGlowingData.kt @@ -4,10 +4,9 @@ import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsCommonBridge import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation import dev.slne.surf.api.paper.nms.bridges.packets.entity.SurfPaperNmsSpawnPackets -import dev.slne.surf.api.paper.server.impl.glow.SurfGlowingApiImpl -import dev.slne.surf.api.paper.server.impl.glow.block.BlockPlayerData import dev.slne.surf.api.paper.server.nms.v26_1.bridges.V26_1SurfPaperNmsGlowingBridgeImpl import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.V26_1PacketOperationImpl +import dev.slne.surf.api.paper.server.nms.v26_1.glow.V26_1SurfGlowingApiImpl import dev.slne.surf.api.paper.server.nms.v26_1.reflection.V26_1Reflection import glm_.shl import net.kyori.adventure.text.format.NamedTextColor @@ -55,7 +54,7 @@ class V26_1BlockGlowingData( fun updateColor() { val player = playerData.player ?: return - SurfGlowingApiImpl.INSTANCE.makeGlowing( + V26_1SurfGlowingApiImpl.INSTANCE.makeGlowing( entityId, uuid.toString(), player, @@ -66,7 +65,7 @@ class V26_1BlockGlowingData( fun remove() { playerData.player?.let { SurfPaperNmsSpawnPackets.despawn(entityId).execute(it) } - SurfGlowingApiImpl.INSTANCE.removeGlowing(entityId, playerData.uuid) + V26_1SurfGlowingApiImpl.INSTANCE.removeGlowing(entityId, playerData.uuid) } private fun initialize() { diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityGlowingData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityGlowingData.kt new file mode 100644 index 000000000..fb7370f7b --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityGlowingData.kt @@ -0,0 +1,73 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.glow.entity + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation +import dev.slne.surf.api.paper.server.nms.v26_1.bridges.V26_1SurfPaperNmsGlowingBridgeImpl +import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.V26_1PacketOperationImpl +import dev.slne.surf.api.paper.server.nms.v26_1.glow.V26_1SurfGlowingApiImpl +import dev.slne.surf.api.paper.server.nms.v26_1.glow.V26_1TeamData +import glm_.and +import glm_.or +import net.minecraft.ChatFormatting + +data class EntityGlowingData( + val playerData: EntityPlayerData, + val entityId: Int, + val teamId: String, + var color: ChatFormatting?, + var otherFlags: Byte, +) { + + @OptIn(NmsUseWithCaution::class) + fun sendTeamColor(): PacketOperation { + val color = color ?: return V26_1PacketOperationImpl.empty() + val teamData = V26_1TeamData.getByColor(color) + + val operation = PacketOperation.start() + if (teamData.markSeen(playerData.uuid)) { + operation.add(V26_1SurfPaperNmsGlowingBridgeImpl.INSTANCE.createTeam(teamData)) + } + operation.add(V26_1SurfPaperNmsGlowingBridgeImpl.INSTANCE.addEntityToTeam(teamData, teamId)) + + return operation + } + + @OptIn(NmsUseWithCaution::class) + fun removeFromTeam(): PacketOperation { + val color = color ?: return V26_1PacketOperationImpl.empty() + val teamData = V26_1TeamData.getByColorOrNull(color) ?: return V26_1PacketOperationImpl.empty() + + val operation = PacketOperation.start() + if (teamData.removeSeen(playerData.uuid)) { + operation.add( + V26_1SurfPaperNmsGlowingBridgeImpl.INSTANCE.removeEntityFromTeam( + teamData, + teamId + ) + ) + } + + return operation + } + + @OptIn(NmsUseWithCaution::class) + fun sendGlowingFlag(enabled: Boolean, ignorePacket: Boolean = false): PacketOperation { + val newFlags = if (enabled) { + otherFlags or V26_1SurfGlowingApiImpl.glowingFlag + } else { + otherFlags and V26_1SurfGlowingApiImpl.glowingFlag.inv() + } + + return V26_1SurfPaperNmsGlowingBridgeImpl.INSTANCE.setEntityFlags( + entityId, + newFlags, + ignorePacket + ) + } + + fun computeFlags(): Byte { + return (otherFlags and V26_1SurfGlowingApiImpl.glowingFlag.inv()).or( + if (color != null) V26_1SurfGlowingApiImpl.glowingFlag else 0 + ) + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityPlayerData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityPlayerData.kt new file mode 100644 index 000000000..7bf507177 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityPlayerData.kt @@ -0,0 +1,8 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.glow.entity + +import java.util.* +import java.util.concurrent.ConcurrentHashMap + +data class EntityPlayerData(val uuid: UUID) { + val entities = ConcurrentHashMap() +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1GlowingPacketListener.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1GlowingPacketListener.kt index 44c3e8c5f..41ec839cf 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1GlowingPacketListener.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1GlowingPacketListener.kt @@ -7,7 +7,7 @@ import dev.slne.surf.api.core.util.toMutableObjectList import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.packet.listener.listener.PacketListener import dev.slne.surf.api.paper.packet.listener.listener.annotation.ClientboundListener -import dev.slne.surf.api.paper.server.impl.glow.SurfGlowingApiImpl +import dev.slne.surf.api.paper.server.nms.v26_1.glow.V26_1SurfGlowingApiImpl import dev.slne.surf.api.paper.server.nms.v26_1.reflection.V26_1Reflection import glm_.or import net.minecraft.network.protocol.Packet @@ -60,7 +60,7 @@ object V26_1GlowingPacketListener : PacketListener { return packet } - val playerData = SurfGlowingApiImpl.getEntityPlayerData(player) ?: return packet + val playerData = V26_1SurfGlowingApiImpl.getEntityPlayerData(player) ?: return packet val glowingData = playerData.entities.get(packet.id) ?: return packet val incoming = packet.packedItems var flagsFound = false @@ -74,7 +74,7 @@ object V26_1GlowingPacketListener : PacketListener { flagsFound = true val current = dataValue.value as Byte glowingData.otherFlags = current - val withGlow: Byte = current or SurfGlowingApiImpl.glowingFlag + val withGlow: Byte = current or V26_1SurfGlowingApiImpl.glowingFlag if (withGlow != current) { edited = true @@ -88,7 +88,7 @@ object V26_1GlowingPacketListener : PacketListener { } if (!edited && !flagsFound) { - val withGlow = glowingData.otherFlags or SurfGlowingApiImpl.glowingFlag + val withGlow = glowingData.otherFlags or V26_1SurfGlowingApiImpl.glowingFlag if (withGlow != 0.toByte()) { edited = true newItems.add(DataValue(dataFlagsSharedId, dataFlagsShared.serializer, withGlow)) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/lore/V26_1PacketLoreRegistry.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/lore/V26_1PacketLoreRegistry.kt new file mode 100644 index 000000000..1f94c23d2 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/lore/V26_1PacketLoreRegistry.kt @@ -0,0 +1,24 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.packet.lore + +import dev.slne.surf.api.paper.nms.common.PacketLoreRegistry +import dev.slne.surf.api.paper.packet.lore.SurfPaperPacketLoreHandler +import org.bukkit.NamespacedKey +import org.bukkit.plugin.Plugin + +class V26_1PacketLoreRegistry : PacketLoreRegistry { + override fun register(plugin: Plugin, identifier: NamespacedKey, listener: SurfPaperPacketLoreHandler) { + V26_1PacketLoreListener.register(plugin, identifier, listener) + } + + override fun register(plugin: Plugin, listener: SurfPaperPacketLoreHandler) { + V26_1PacketLoreListener.register(plugin, listener) + } + + override fun unregister(identifier: NamespacedKey) { + V26_1PacketLoreListener.unregister(identifier) + } + + override fun unregister(plugin: Plugin) { + V26_1PacketLoreListener.unregister(plugin) + } +} diff --git a/surf-api-paper/surf-api-paper-server/build.gradle.kts b/surf-api-paper/surf-api-paper-server/build.gradle.kts index eb16d18ae..cc8d49581 100644 --- a/surf-api-paper/surf-api-paper-server/build.gradle.kts +++ b/surf-api-paper/surf-api-paper-server/build.gradle.kts @@ -18,9 +18,13 @@ kotlin { dependencies { api(projects.surfApiPaper.surfApiPaper) api(projects.surfApiCore.surfApiCoreServer) + api(projects.surfApiPaper.surfApiPaperNms.surfApiPaperNmsCommon) paperweight.paperDevBundle(libs.paper.api.get().version) + // Version-specific NMS modules (runtime only - loaded via ServiceLoader) + runtimeOnly(projects.surfApiPaper.surfApiPaperNms.surfApiPaperNmsV261) + compileOnly(libs.placeholder.api) // -------------------- Paper Libraries -------------------- // diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/PaperInstance.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/PaperInstance.kt index 8336850df..536b0cc4e 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/PaperInstance.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/PaperInstance.kt @@ -6,14 +6,12 @@ import dev.slne.surf.api.paper.server.impl.SurfApiPaperImpl import dev.slne.surf.api.paper.server.inventory.framework.InventoryLoader import dev.slne.surf.api.paper.server.listener.ListenerManager import dev.slne.surf.api.paper.server.packet.PacketApiLoader -import dev.slne.surf.api.paper.server.reflection.Reflection object PaperInstance : CoreInstance() { override suspend fun onLoad() { super.onLoad() - initObjects() PacketApiLoader.onLoad() InventoryLoader.load() } @@ -34,8 +32,4 @@ object PaperInstance : CoreInstance() { PacketApiLoader.onDisable() InventoryLoader.disable() } - - private fun initObjects() { - Reflection - } } \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/GlowingListener.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/GlowingListener.kt index 21d80683b..6df1adfe9 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/GlowingListener.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/GlowingListener.kt @@ -1,32 +1,32 @@ package dev.slne.surf.api.paper.server.impl.glow -import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation -import dev.slne.surf.api.paper.util.chunkX -import dev.slne.surf.api.paper.util.chunkZ +import dev.slne.surf.api.paper.nms.common.GlowingLifecycleHandler +import dev.slne.surf.api.paper.nms.common.NmsProvider import io.papermc.paper.event.packet.PlayerChunkLoadEvent import org.bukkit.event.EventHandler import org.bukkit.event.Listener import org.bukkit.event.player.PlayerQuitEvent object GlowingListener : Listener { + private val glowingLifecycleHandler: GlowingLifecycleHandler by lazy { + NmsProvider.current.createGlowingLifecycleHandler() + } + @EventHandler fun onPlayerQuit(event: PlayerQuitEvent) { - SurfGlowingApiImpl.removeAllGlowingOnQuit(event.player) + glowingLifecycleHandler.removeAllGlowingOnQuit(event.player) } @EventHandler fun onPlayerChunkLoad(event: PlayerChunkLoadEvent) { - val playerData = SurfGlowingApiImpl.getBlockPlayerData(event.player) ?: return - val blockDataList = playerData.blocks - if (blockDataList.isEmpty()) return - - val spawnOperation = PacketOperation.start() - for ((loc, block) in blockDataList) { - val chunk = event.chunk - if (loc.chunkX != chunk.x || loc.chunkZ != chunk.z || loc.world != chunk.world) continue - spawnOperation.add(block.spawn()) - } + val chunk = event.chunk + val operation = glowingLifecycleHandler.getBlockGlowSpawnOperationForChunk( + event.player, + chunk.x, + chunk.z, + chunk.world + ) ?: return - spawnOperation.execute(event.player) + operation.execute(event.player) } } \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/packet/SurfPaperPacketApiImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/packet/SurfPaperPacketApiImpl.kt index 816d34886..7df74edc4 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/packet/SurfPaperPacketApiImpl.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/packet/SurfPaperPacketApiImpl.kt @@ -2,14 +2,17 @@ package dev.slne.surf.api.paper.server.impl.packet import com.google.auto.service.AutoService import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.common.NmsProvider +import dev.slne.surf.api.paper.nms.common.PacketLoreRegistry import dev.slne.surf.api.paper.packet.SurfPaperPacketApi import dev.slne.surf.api.paper.packet.lore.SurfPaperPacketLoreHandler -import dev.slne.surf.api.paper.server.packet.lore.PacketLoreListener import org.bukkit.NamespacedKey import org.bukkit.plugin.Plugin @AutoService(SurfPaperPacketApi::class) class SurfPaperPacketApiImpl : SurfPaperPacketApi { + private val packetLoreRegistry: PacketLoreRegistry = NmsProvider.current.createPacketLoreRegistry() + init { checkInstantiationByServiceLoader() } @@ -19,21 +22,21 @@ class SurfPaperPacketApiImpl : SurfPaperPacketApi { identifier: NamespacedKey, listener: SurfPaperPacketLoreHandler ) { - PacketLoreListener.register(plugin, identifier, listener) + packetLoreRegistry.register(plugin, identifier, listener) } override fun registerPacketLoreListenerGlobal( plugin: Plugin, listener: SurfPaperPacketLoreHandler ) { - PacketLoreListener.register(plugin, listener) + packetLoreRegistry.register(plugin, listener) } override fun unregisterPacketLoreListener(plugin: Plugin) { - PacketLoreListener.unregister(plugin) + packetLoreRegistry.unregister(plugin) } override fun unregisterPacketLoreListener(identifier: NamespacedKey) { - PacketLoreListener.unregister(identifier) + packetLoreRegistry.unregister(identifier) } } diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt index 76266c379..9489d5b5c 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt @@ -5,16 +5,18 @@ import dev.slne.surf.api.core.extensions.packetEvents import dev.slne.surf.api.paper.event.register import dev.slne.surf.api.paper.event.unregister import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.common.NmsProvider import dev.slne.surf.api.paper.packet.listener.SurfPaperPacketListenerApi -import dev.slne.surf.api.paper.server.impl.glow.GlowingPacketListener +import dev.slne.surf.api.paper.packet.listener.listener.PacketListener import dev.slne.surf.api.paper.server.packet.listener.PlayerChannelInjector -import dev.slne.surf.api.paper.server.packet.lore.PacketLoreListener import dev.slne.surf.api.paper.server.packet.lore.PluginDisablePacketLoreListener import dev.slne.surf.api.paper.server.plugin import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder object PacketApiLoader { + private var versionPacketListeners: List = emptyList() + fun onLoad() { setupPacketEvents() } @@ -22,17 +24,31 @@ object PacketApiLoader { @OptIn(NmsUseWithCaution::class) fun onEnable() { packetEvents.init() - SurfPaperPacketListenerApi.registerListeners(PacketLoreListener) - SurfPaperPacketListenerApi.registerListeners(GlowingPacketListener) + + // Register version-specific packet listeners from NmsProvider + val provider = NmsProvider.current + versionPacketListeners = provider.createPacketListeners() + for (listener in versionPacketListeners) { + SurfPaperPacketListenerApi.registerListeners(listener) + } PlayerChannelInjector.register() PluginDisablePacketLoreListener.register() + + provider.initialize() } @OptIn(NmsUseWithCaution::class) fun onDisable() { + val provider = NmsProvider.current + provider.shutdown() + packetEvents.terminate() - SurfPaperPacketListenerApi.unregisterListeners(PacketLoreListener) + for (listener in versionPacketListeners) { + SurfPaperPacketListenerApi.unregisterListeners(listener) + } + versionPacketListeners = emptyList() + PluginDisablePacketLoreListener.unregister() PlayerChannelInjector.unregister() } diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/listener/PlayerChannelInjector.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/listener/PlayerChannelInjector.kt index 20eb74efe..00d2c28d9 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/listener/PlayerChannelInjector.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/listener/PlayerChannelInjector.kt @@ -10,10 +10,11 @@ import dev.slne.surf.api.core.reflection.createProxy import dev.slne.surf.api.core.util.logger import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge +import dev.slne.surf.api.paper.nms.common.NmsPacketBridgeHandler +import dev.slne.surf.api.paper.nms.common.NmsProvider +import dev.slne.surf.api.paper.nms.listener.packets.NmsPacket import dev.slne.surf.api.paper.packet.listener.SurfPaperPacketListenerApi import dev.slne.surf.api.paper.server.impl.nms.SurfPaperNmsBridgeImpl -import dev.slne.surf.api.paper.server.impl.nms.listener.packets.NmsPacketImpl -import dev.slne.surf.api.paper.server.impl.nms.listener.packets.PacketRegistry import dev.slne.surf.api.paper.server.impl.packet.listener.SurfPaperPacketListenerApiImpl import dev.slne.surf.api.paper.server.nms.toNms import dev.slne.surf.api.paper.server.plugin @@ -127,6 +128,8 @@ object PlayerChannelInjector : Listener { private val bridge = SurfPaperNmsBridge.INSTANCE as SurfPaperNmsBridgeImpl private val packetListenerApi = SurfPaperPacketListenerApi.INSTANCE as SurfPaperPacketListenerApiImpl + private val packetBridgeHandler: NmsPacketBridgeHandler = + NmsProvider.current.createPacketBridgeHandler() @Volatile var connection: Connection? = null @@ -192,7 +195,7 @@ object PlayerChannelInjector : Listener { serverPlayer: ServerPlayer?, packet: Packet<*>, ): Packet<*>? { - val apiPacket = PacketRegistry.createServerboundPacketOrNull(packet) + val apiPacket = packetBridgeHandler.wrapServerboundPacket(packet) if (apiPacket != null) { // we have an api packet wrapper for this packet val resultApi = this.bridge.handleServerboundPacket( @@ -201,7 +204,7 @@ object PlayerChannelInjector : Listener { ) if (resultApi != null) { // we may have a modified packet - return NmsPacketImpl.getFromApi(resultApi).nmsPacket + return packetBridgeHandler.unwrapPacket(resultApi) as Packet<*> } } else { return packet // no api packet wrapper, so we just return the original packet @@ -214,7 +217,7 @@ object PlayerChannelInjector : Listener { serverPlayer: ServerPlayer?, packet: Packet<*>, ): Packet<*>? { - val apiPacket = PacketRegistry.createClientboundPacketOrNull(packet) + val apiPacket = packetBridgeHandler.wrapClientboundPacket(packet) if (apiPacket != null) { val resultApi = this.bridge.handleClientboundPacket( @@ -223,7 +226,7 @@ object PlayerChannelInjector : Listener { ) if (resultApi != null) { - return NmsPacketImpl.getFromApi(resultApi).nmsPacket + return packetBridgeHandler.unwrapPacket(resultApi) as Packet<*> } } else { return packet diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/lore/PluginDisablePacketLoreListener.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/lore/PluginDisablePacketLoreListener.kt index 907051f7c..888069bae 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/lore/PluginDisablePacketLoreListener.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/lore/PluginDisablePacketLoreListener.kt @@ -1,13 +1,15 @@ package dev.slne.surf.api.paper.server.packet.lore +import dev.slne.surf.api.paper.nms.common.NmsProvider import org.bukkit.event.EventHandler import org.bukkit.event.Listener import org.bukkit.event.server.PluginDisableEvent object PluginDisablePacketLoreListener : Listener { + private val packetLoreRegistry by lazy { NmsProvider.current.createPacketLoreRegistry() } @EventHandler fun onPluginDisable(event: PluginDisableEvent) { - PacketLoreListener.unregister(event.plugin) + packetLoreRegistry.unregister(event.plugin) } } \ No newline at end of file From 30bd574b4ae337b00aaf0c1f7ebf6d2c6f55f693 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Apr 2026 20:54:08 +0000 Subject: [PATCH 05/34] feat: remove @AutoService from old impls, fix proxy delegation conflicts - Remove SurfPaperNmsBridgeProxy (SurfPaperNmsBridgeImpl is version-agnostic, no proxy needed) - Remove @AutoService from 16 old bridge implementations that now have proxies - Keep SurfPaperNmsBridgeImpl with @AutoService as it handles listener dispatching - Old impl classes remain as dead code for now (can be cleaned up later) Agent-Logs-Url: https://github.com/SLNE-Development/surf-api/sessions/b4c8c86c-2741-4ab8-aae6-f9f6995c0e54 Co-authored-by: TheBjoRedCraft <143264463+TheBjoRedCraft@users.noreply.github.com> --- .../paper/server/impl/glow/SurfGlowingApiImpl.kt | 2 -- .../SurfPaperNmsCommandArgumentTypesBridgeImpl.kt | 4 ---- .../nms/bridges/SurfPaperNmsCommonBridgeImpl.kt | 4 ---- .../nms/bridges/SurfPaperNmsEntityBridgeImpl.kt | 4 ---- .../nms/bridges/SurfPaperNmsGlowingBridgeImpl.kt | 2 -- .../impl/nms/bridges/SurfPaperNmsItemBridgeImpl.kt | 4 ---- .../nms/bridges/SurfPaperNmsLootTableBridgeImpl.kt | 2 -- .../impl/nms/bridges/SurfPaperNmsNbtBridgeImpl.kt | 2 -- .../nms/bridges/SurfPaperNmsStatsBridgeImpl.kt | 4 ---- .../packets/SurfPaperNmsPacketBridgesImpl.kt | 4 ---- .../packets/block/SurfPaperNmsBlockPacketsImpl.kt | 4 ---- .../packets/entity/SurfPaperNmsSpawnPacketsImpl.kt | 2 -- .../player/SurfPaperNmsPlayerChatPacketsImpl.kt | 2 -- .../player/SurfPaperNmsPlayerPacketsImpl.kt | 4 ---- .../player/SurfPaperNmsPlayerToastPacketsImpl.kt | 2 -- .../server/impl/region/TickThreadGuardImpl.kt | 4 ---- .../paper/server/proxy/SurfPaperNmsBridgeProxy.kt | 14 -------------- 17 files changed, 64 deletions(-) delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsBridgeProxy.kt diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/SurfGlowingApiImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/SurfGlowingApiImpl.kt index 67ad7d01a..02c4efb00 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/SurfGlowingApiImpl.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/SurfGlowingApiImpl.kt @@ -2,7 +2,6 @@ package dev.slne.surf.api.paper.server.impl.glow import com.github.shynixn.mccoroutine.folia.entityDispatcher import com.github.shynixn.mccoroutine.folia.launch -import com.google.auto.service.AutoService import dev.slne.surf.api.paper.extensions.server import dev.slne.surf.api.paper.glow.SurfGlowingApi import dev.slne.surf.api.paper.nms.NmsUseWithCaution @@ -24,7 +23,6 @@ import org.bukkit.entity.Player import java.util.* import java.util.concurrent.ConcurrentHashMap -@AutoService(SurfGlowingApi::class) class SurfGlowingApiImpl : SurfGlowingApi { @OptIn(NmsUseWithCaution::class) diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsCommandArgumentTypesBridgeImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsCommandArgumentTypesBridgeImpl.kt index 6040a8c92..da08bdcbe 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsCommandArgumentTypesBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsCommandArgumentTypesBridgeImpl.kt @@ -1,10 +1,8 @@ package dev.slne.surf.api.paper.server.impl.nms.bridges -import com.google.auto.service.AutoService import com.mojang.brigadier.arguments.ArgumentType import com.mojang.brigadier.context.CommandContext import com.mojang.brigadier.exceptions.CommandSyntaxException -import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsCommandArgumentTypesBridge import dev.slne.surf.api.paper.server.nms.AdventureNBT @@ -21,10 +19,8 @@ import java.lang.reflect.InvocationHandler import java.util.concurrent.ConcurrentHashMap @NmsUseWithCaution -@AutoService(SurfPaperNmsCommandArgumentTypesBridge::class) class SurfPaperNmsCommandArgumentTypesBridgeImpl : SurfPaperNmsCommandArgumentTypesBridge { init { - checkInstantiationByServiceLoader() } override fun compoundTag(): ArgumentType<*> { diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsCommonBridgeImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsCommonBridgeImpl.kt index ae0d152e8..b12d822f5 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsCommonBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsCommonBridgeImpl.kt @@ -1,7 +1,5 @@ package dev.slne.surf.api.paper.server.impl.nms.bridges -import com.google.auto.service.AutoService -import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader import dev.slne.surf.api.paper.dialog.noticeDialogWithBuilder import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsCommonBridge @@ -21,11 +19,9 @@ import org.bukkit.block.data.BlockData import org.bukkit.entity.Player import java.net.InetSocketAddress -@AutoService(SurfPaperNmsCommonBridge::class) @NmsUseWithCaution class SurfPaperNmsCommonBridgeImpl : SurfPaperNmsCommonBridge { init { - checkInstantiationByServiceLoader() } @Suppress("DEPRECATION") diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsEntityBridgeImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsEntityBridgeImpl.kt index 88268e8c2..515f5f793 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsEntityBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsEntityBridgeImpl.kt @@ -1,10 +1,8 @@ package dev.slne.surf.api.paper.server.impl.nms.bridges import ca.spottedleaf.moonrise.common.util.TickThread -import com.google.auto.service.AutoService import com.mojang.brigadier.exceptions.CommandSyntaxException import dev.jorel.commandapi.exceptions.WrapperCommandSyntaxException -import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsEntityBridge import dev.slne.surf.api.paper.server.nms.AdventureNBT @@ -20,10 +18,8 @@ import org.bukkit.World import org.bukkit.entity.EntityType @NmsUseWithCaution -@AutoService(SurfPaperNmsEntityBridge::class) class SurfPaperNmsEntityBridgeImpl : SurfPaperNmsEntityBridge { init { - checkInstantiationByServiceLoader() } @Suppress("UnstableApiUsage") diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsGlowingBridgeImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsGlowingBridgeImpl.kt index 9e6a3957f..1fc74c7b3 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsGlowingBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsGlowingBridgeImpl.kt @@ -1,6 +1,5 @@ package dev.slne.surf.api.paper.server.impl.nms.bridges -import com.google.auto.service.AutoService import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsGlowingBridge import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation @@ -15,7 +14,6 @@ import net.minecraft.network.syncher.SynchedEntityData.DataValue import org.bukkit.entity.Entity @NmsUseWithCaution -@AutoService(SurfPaperNmsGlowingBridge::class) class SurfPaperNmsGlowingBridgeImpl : SurfPaperNmsGlowingBridge { fun createTeam(data: TeamData): PacketOperation = PacketOperationImpl.simple { diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsItemBridgeImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsItemBridgeImpl.kt index 22cbfa5ff..e11608945 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsItemBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsItemBridgeImpl.kt @@ -1,7 +1,5 @@ package dev.slne.surf.api.paper.server.impl.nms.bridges -import com.google.auto.service.AutoService -import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsItemBridge import dev.slne.surf.api.paper.server.nms.nms @@ -9,11 +7,9 @@ import net.minecraft.core.component.DataComponentMap import net.minecraft.core.component.DataComponents import org.bukkit.inventory.ItemType -@AutoService(SurfPaperNmsItemBridge::class) @NmsUseWithCaution class SurfPaperNmsItemBridgeImpl : SurfPaperNmsItemBridge { init { - checkInstantiationByServiceLoader() } override fun setDefaultMaxStackSize(item: ItemType, maxStackSize: Int) { diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsLootTableBridgeImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsLootTableBridgeImpl.kt index 66c622970..e9b7c526d 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsLootTableBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsLootTableBridgeImpl.kt @@ -1,6 +1,5 @@ package dev.slne.surf.api.paper.server.impl.nms.bridges -import com.google.auto.service.AutoService import dev.slne.surf.api.core.util.emptyObjectList import dev.slne.surf.api.core.util.mutableObjectListOf import dev.slne.surf.api.paper.nms.NmsUseWithCaution @@ -18,7 +17,6 @@ import org.bukkit.entity.LivingEntity import org.bukkit.inventory.ItemStack import kotlin.jvm.optionals.getOrNull -@AutoService(SurfPaperNmsLootTableBridge::class) @NmsUseWithCaution class SurfPaperNmsLootTableBridgeImpl : SurfPaperNmsLootTableBridge { override fun getDifferentLootTable( diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsNbtBridgeImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsNbtBridgeImpl.kt index 53ff32738..469486f59 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsNbtBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsNbtBridgeImpl.kt @@ -1,6 +1,5 @@ package dev.slne.surf.api.paper.server.impl.nms.bridges -import com.google.auto.service.AutoService import dev.slne.surf.api.core.util.logger import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsNbtBridge @@ -15,7 +14,6 @@ import org.bukkit.entity.EntityType import org.bukkit.inventory.ItemStack import kotlin.jvm.optionals.getOrNull -@AutoService(SurfPaperNmsNbtBridge::class) @NmsUseWithCaution class SurfPaperNmsNbtBridgeImpl : SurfPaperNmsNbtBridge { diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsStatsBridgeImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsStatsBridgeImpl.kt index 52579d90a..c263f7f9b 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsStatsBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsStatsBridgeImpl.kt @@ -1,18 +1,14 @@ package dev.slne.surf.api.paper.server.impl.nms.bridges -import com.google.auto.service.AutoService -import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsStatsBridge import dev.slne.surf.api.paper.server.nms.toNms import dev.slne.surf.api.paper.server.reflection.Reflection import org.bukkit.entity.Player -@AutoService(SurfPaperNmsStatsBridge::class) @NmsUseWithCaution class SurfPaperNmsStatsBridgeImpl : SurfPaperNmsStatsBridge { init { - checkInstantiationByServiceLoader() } override fun getPlayerStatsAsJson(player: Player): String { diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/SurfPaperNmsPacketBridgesImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/SurfPaperNmsPacketBridgesImpl.kt index e7be05399..cf399fe2e 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/SurfPaperNmsPacketBridgesImpl.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/SurfPaperNmsPacketBridgesImpl.kt @@ -1,15 +1,11 @@ package dev.slne.surf.api.paper.server.impl.nms.bridges.packets -import com.google.auto.service.AutoService -import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.packets.SurfPaperNmsPacketBridges @NmsUseWithCaution -@AutoService(SurfPaperNmsPacketBridges::class) class SurfPaperNmsPacketBridgesImpl : SurfPaperNmsPacketBridges { init { - checkInstantiationByServiceLoader() } override fun createEmptyPacketOperation(): PacketOperationImpl { diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/block/SurfPaperNmsBlockPacketsImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/block/SurfPaperNmsBlockPacketsImpl.kt index c301a011c..c928aa031 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/block/SurfPaperNmsBlockPacketsImpl.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/block/SurfPaperNmsBlockPacketsImpl.kt @@ -2,8 +2,6 @@ package dev.slne.surf.api.paper.server.impl.nms.bridges.packets.block -import com.google.auto.service.AutoService -import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.packets.block.SurfPaperNmsBlockPackets import dev.slne.surf.api.paper.server.impl.nms.bridges.packets.PacketOperationImpl @@ -12,11 +10,9 @@ import io.papermc.paper.math.BlockPosition import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket import org.bukkit.block.data.BlockData -@AutoService(SurfPaperNmsBlockPackets::class) @NmsUseWithCaution class SurfPaperNmsBlockPacketsImpl : SurfPaperNmsBlockPackets { init { - checkInstantiationByServiceLoader() } override fun updateBlockData(position: BlockPosition, blockData: BlockData) = diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/entity/SurfPaperNmsSpawnPacketsImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/entity/SurfPaperNmsSpawnPacketsImpl.kt index b72a70286..8ecdd16c5 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/entity/SurfPaperNmsSpawnPacketsImpl.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/entity/SurfPaperNmsSpawnPacketsImpl.kt @@ -1,6 +1,5 @@ package dev.slne.surf.api.paper.server.impl.nms.bridges.packets.entity -import com.google.auto.service.AutoService import com.google.common.flogger.StackSize import com.mojang.math.Transformation import dev.slne.surf.api.core.util.logger @@ -29,7 +28,6 @@ import kotlin.experimental.inv import kotlin.experimental.or @Suppress("UnstableApiUsage") -@AutoService(SurfPaperNmsSpawnPackets::class) @NmsUseWithCaution class SurfPaperNmsSpawnPacketsImpl : SurfPaperNmsSpawnPackets { private val log = logger() diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerChatPacketsImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerChatPacketsImpl.kt index 1a89fa287..05b3dc5e6 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerChatPacketsImpl.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerChatPacketsImpl.kt @@ -1,6 +1,5 @@ package dev.slne.surf.api.paper.server.impl.nms.bridges.packets.player -import com.google.auto.service.AutoService import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation import dev.slne.surf.api.paper.nms.bridges.packets.player.LastSeenMessagesPacked @@ -20,7 +19,6 @@ import java.util.* import net.minecraft.network.chat.MessageSignature as NmsMessageSignature @NmsUseWithCaution -@AutoService(SurfPaperNmsPlayerChatPackets::class) class SurfPaperNmsPlayerChatPacketsImpl : SurfPaperNmsPlayerChatPackets { override fun sendPlayerChatMessagePacket( senderUuid: UUID, diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerPacketsImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerPacketsImpl.kt index 1e9f7e7fc..d9d775760 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerPacketsImpl.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerPacketsImpl.kt @@ -2,8 +2,6 @@ package dev.slne.surf.api.paper.server.impl.nms.bridges.packets.player -import com.google.auto.service.AutoService -import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerPackets import dev.slne.surf.api.paper.server.impl.nms.bridges.packets.PacketOperationImpl @@ -17,11 +15,9 @@ import net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket import org.bukkit.event.inventory.InventoryType import org.bukkit.inventory.ItemStack -@AutoService(SurfPaperNmsPlayerPackets::class) @NmsUseWithCaution class SurfPaperNmsPlayerPacketsImpl : SurfPaperNmsPlayerPackets { init { - checkInstantiationByServiceLoader() } override fun openSignEditor( diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerToastPacketsImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerToastPacketsImpl.kt index 38016ef31..c30ec81db 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerToastPacketsImpl.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerToastPacketsImpl.kt @@ -1,6 +1,5 @@ package dev.slne.surf.api.paper.server.impl.nms.bridges.packets.player -import com.google.auto.service.AutoService import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToastPackets import dev.slne.surf.api.paper.nms.bridges.packets.player.toast.Toast @@ -16,7 +15,6 @@ import java.util.* @NmsUseWithCaution -@AutoService(SurfPaperNmsPlayerToastPackets::class) class SurfPaperNmsPlayerToastPacketsImpl : SurfPaperNmsPlayerToastPackets { override fun showToast(toast: Toast) = PacketOperationImpl.complex { _, packets -> val id = Identifier.fromNamespaceAndPath("surfapi", "toast_${UUID.randomUUID()}") diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/region/TickThreadGuardImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/region/TickThreadGuardImpl.kt index 3ee138d93..1c892806f 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/region/TickThreadGuardImpl.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/region/TickThreadGuardImpl.kt @@ -1,8 +1,6 @@ package dev.slne.surf.api.paper.server.impl.region import ca.spottedleaf.moonrise.common.util.TickThread -import com.google.auto.service.AutoService -import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader import dev.slne.surf.api.paper.region.TickThreadGuard import dev.slne.surf.api.paper.server.nms.toNms import dev.slne.surf.api.paper.util.chunkX @@ -15,10 +13,8 @@ import org.bukkit.entity.Entity import org.bukkit.util.BoundingBox @Suppress("UnstableApiUsage") -@AutoService(TickThreadGuard::class) class TickThreadGuardImpl : TickThreadGuard { init { - checkInstantiationByServiceLoader() } override fun ensureTickThread(world: World, pos: Position, reason: String) { diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsBridgeProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsBridgeProxy.kt deleted file mode 100644 index 2fce4f127..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsBridgeProxy.kt +++ /dev/null @@ -1,14 +0,0 @@ -package dev.slne.surf.api.paper.server.proxy - -import com.google.auto.service.AutoService -import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge -import dev.slne.surf.api.paper.nms.common.NmsProvider - -@NmsUseWithCaution -@AutoService(SurfPaperNmsBridge::class) -class SurfPaperNmsBridgeProxy : - SurfPaperNmsBridge by NmsProvider.current.createNmsBridge() { - init { checkInstantiationByServiceLoader() } -} From c7e6336e9962f3a9862fa7334ca4637905a41796 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Apr 2026 05:28:11 +0000 Subject: [PATCH 06/34] feat: implement 1.21.11 NMS module and add NMS template generator Agent-Logs-Url: https://github.com/SLNE-Development/surf-api/sessions/360d5417-e18a-48e5-8566-1b1629da9e01 Co-authored-by: TheBjoRedCraft <143264463+TheBjoRedCraft@users.noreply.github.com> --- surf-api-generator/build.gradle.kts | 10 + .../slne/surf/api/gen/nms/NmsGeneratorMain.kt | 30 ++ .../surf/api/gen/nms/NmsTemplateGenerator.kt | 127 ++++++ .../slne/surf/api/gen/nms/NmsVersionConfig.kt | 20 + .../surf/api/gen/nms/NmsVersionConfigs.kt | 80 ++++ .../V1_21_11NmsPacketBridgeHandler.kt | 28 ++ .../nms/v1_21_11/V1_21_11NmsProvider.kt | 117 +++--- .../bridges/V1_21_11SurfPaperNmsBridgeImpl.kt | 128 ++++++ ...fPaperNmsCommandArgumentTypesBridgeImpl.kt | 107 +++++ .../V1_21_11SurfPaperNmsCommonBridgeImpl.kt | 83 ++++ .../V1_21_11SurfPaperNmsEntityBridgeImpl.kt | 53 +++ .../V1_21_11SurfPaperNmsGlowingBridgeImpl.kt | 60 +++ .../V1_21_11SurfPaperNmsItemBridgeImpl.kt | 24 ++ ...V1_21_11SurfPaperNmsLootTableBridgeImpl.kt | 55 +++ .../V1_21_11SurfPaperNmsNbtBridgeImpl.kt | 62 +++ .../V1_21_11SurfPaperNmsStatsBridgeImpl.kt | 21 + .../packets/V1_21_11PacketOperationImpl.kt | 115 ++++++ .../V1_21_11SurfPaperNmsPacketBridgesImpl.kt | 12 + .../V1_21_11SurfPaperNmsBlockPacketsImpl.kt | 31 ++ .../V1_21_11SurfPaperNmsSpawnPacketsImpl.kt | 207 ++++++++++ ..._21_11SurfPaperNmsPlayerChatPacketsImpl.kt | 64 +++ .../V1_21_11SurfPaperNmsPlayerPacketsImpl.kt | 54 +++ ...21_11SurfPaperNmsPlayerToastPacketsImpl.kt | 60 +++ .../nms/v1_21_11/extensions/AdventureNBT.kt | 96 +++++ .../nms/v1_21_11/extensions/nms-extensions.kt | 150 +++++++ .../glow/V1_21_11GlowingLifecycleHandler.kt | 33 ++ .../glow/V1_21_11SurfGlowingApiImpl.kt | 172 ++++++++ .../nms/v1_21_11/glow/V1_21_11TeamData.kt | 40 ++ .../v1_21_11/glow/block/BlockPlayerData.kt | 11 + .../glow/block/V1_21_11BlockGlowingData.kt | 80 ++++ .../v1_21_11/glow/entity/EntityGlowingData.kt | 73 ++++ .../v1_21_11/glow/entity/EntityPlayerData.kt | 8 + .../listener/packets/V1_21_11NmsPacketImpl.kt | 24 ++ .../packets/V1_21_11PacketRegistry.kt | 78 ++++ ...V1_21_11ClientboundDisconnectPacketImpl.kt | 14 + ...V1_21_11ClientboundSystemChatPacketImpl.kt | 25 ++ .../V1_21_11NmsClientboundPacketImpl.kt | 12 + .../V1_21_11CommandSuggestionPacketImpl.kt | 13 + .../V1_21_11NmsServerboundPacketImpl.kt | 10 + .../V1_21_11RenameItemPacketImpl.kt | 11 + ...21_11ServerboundCustomPayloadPacketImpl.kt | 42 ++ .../V1_21_11SignUpdatePacketImpl.kt | 19 + .../listener/V1_21_11GlowingPacketListener.kt | 100 +++++ .../packet/lore/V1_21_11PacketLoreListener.kt | 388 ++++++++++++++++++ .../packet/lore/V1_21_11PacketLoreRegistry.kt | 24 ++ .../reflection/V1_21_11EntityProxy.kt | 23 ++ .../v1_21_11/reflection/V1_21_11Reflection.kt | 37 ++ .../V1_21_11ServerConnectionListenerProxy.kt | 12 + .../V1_21_11ServerStatsCounterProxy.kt | 20 + ...1_21_11VanillaArgumentProviderImplProxy.kt | 15 + .../V1_21_11VanillaArgumentProviderProxy.kt | 14 + .../region/V1_21_11TickThreadGuard.kt | 65 +++ .../surf-api-paper-server/build.gradle.kts | 1 + 53 files changed, 3089 insertions(+), 69 deletions(-) create mode 100644 surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsGeneratorMain.kt create mode 100644 surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsTemplateGenerator.kt create mode 100644 surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsVersionConfig.kt create mode 100644 surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsVersionConfigs.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsPacketBridgeHandler.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsBridgeImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsCommandArgumentTypesBridgeImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsCommonBridgeImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsEntityBridgeImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsGlowingBridgeImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsItemBridgeImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsLootTableBridgeImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsNbtBridgeImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsStatsBridgeImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/V1_21_11PacketOperationImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/V1_21_11SurfPaperNmsPacketBridgesImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/block/V1_21_11SurfPaperNmsBlockPacketsImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/entity/V1_21_11SurfPaperNmsSpawnPacketsImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/player/V1_21_11SurfPaperNmsPlayerChatPacketsImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/player/V1_21_11SurfPaperNmsPlayerPacketsImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/player/V1_21_11SurfPaperNmsPlayerToastPacketsImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/extensions/AdventureNBT.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/extensions/nms-extensions.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11GlowingLifecycleHandler.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11SurfGlowingApiImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11TeamData.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/block/BlockPlayerData.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/block/V1_21_11BlockGlowingData.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/entity/EntityGlowingData.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/entity/EntityPlayerData.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/V1_21_11NmsPacketImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/V1_21_11PacketRegistry.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/clientbound/V1_21_11ClientboundDisconnectPacketImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/clientbound/V1_21_11ClientboundSystemChatPacketImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/clientbound/V1_21_11NmsClientboundPacketImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/serverbound/V1_21_11CommandSuggestionPacketImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/serverbound/V1_21_11NmsServerboundPacketImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/serverbound/V1_21_11RenameItemPacketImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/serverbound/V1_21_11ServerboundCustomPayloadPacketImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/serverbound/V1_21_11SignUpdatePacketImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/listener/V1_21_11GlowingPacketListener.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/lore/V1_21_11PacketLoreListener.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/lore/V1_21_11PacketLoreRegistry.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11EntityProxy.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11Reflection.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11ServerConnectionListenerProxy.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11ServerStatsCounterProxy.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11VanillaArgumentProviderImplProxy.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11VanillaArgumentProviderProxy.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/region/V1_21_11TickThreadGuard.kt diff --git a/surf-api-generator/build.gradle.kts b/surf-api-generator/build.gradle.kts index 182a80282..d808e0f5c 100644 --- a/surf-api-generator/build.gradle.kts +++ b/surf-api-generator/build.gradle.kts @@ -105,6 +105,16 @@ tasks.register("generate") { args(projectDir.toPath().resolve("generated").toString()) } +tasks.register("generateNms") { + group = "generation" + description = "Generate version-specific NMS modules from the reference (v26-1) sources" + dependsOn(tasks.classes) + + mainClass.set("dev.slne.surf.api.gen.nms.NmsGeneratorMainKt") + classpath(sourceSets.main.map { it.runtimeClasspath }) + args(rootProject.projectDir.absolutePath) +} + private fun String.downloadTo(output: Path) { uri(this).toURL().openStream() diff --git a/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsGeneratorMain.kt b/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsGeneratorMain.kt new file mode 100644 index 000000000..dc9019d81 --- /dev/null +++ b/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsGeneratorMain.kt @@ -0,0 +1,30 @@ +package dev.slne.surf.api.gen.nms + +import java.nio.file.Path +import kotlin.io.path.Path + +/** + * Entry point for NMS version-specific code generation. + * + * Usage: Run with repo root as the first argument. + * From Gradle: `./gradlew :surf-api-generator:generateNms` + */ +fun main(args: Array) { + val repoRoot = if (args.isNotEmpty()) Path(args[0]) else Path("..") + + println("Generating NMS version-specific code from reference ${NmsVersionConfigs.REFERENCE_VERSION_ID}...") + + val referenceSourceRoot = repoRoot + .resolve(NmsVersionConfigs.REFERENCE_MODULE_PATH) + .resolve("src/main/kotlin") + + val generator = NmsTemplateGenerator( + referenceVersionId = NmsVersionConfigs.REFERENCE_VERSION_ID, + referenceClassPrefix = NmsVersionConfigs.REFERENCE_CLASS_PREFIX, + referenceSourceRoot = referenceSourceRoot, + targets = NmsVersionConfigs.ALL_TARGETS, + ) + + val totalGenerated = generator.generate(repoRoot) + println("NMS generation complete: $totalGenerated files generated across ${NmsVersionConfigs.ALL_TARGETS.size} target(s)") +} diff --git a/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsTemplateGenerator.kt b/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsTemplateGenerator.kt new file mode 100644 index 000000000..47da3ad88 --- /dev/null +++ b/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsTemplateGenerator.kt @@ -0,0 +1,127 @@ +package dev.slne.surf.api.gen.nms + +import java.nio.file.Path +import kotlin.io.path.* + +/** + * Generates version-specific NMS module source code from a reference module. + * + * The reference module (e.g. v26-1) serves as the canonical "template". + * This generator copies every source file, applying version-specific + * transformations: + * + * 1. Package name replacement (reference version → target version) + * 2. Class prefix replacement (e.g. V26_1 → V1_21_11) + * 3. Import replacements for changed NMS APIs + * 4. Code-level replacements for renamed methods/classes + * 5. Per-file custom transformers for structural differences + */ +class NmsTemplateGenerator( + private val referenceVersionId: String, + private val referenceClassPrefix: String, + private val referenceSourceRoot: Path, + private val targets: List, +) { + + /** + * Generate all target modules from the reference source files. + * + * @param repoRoot absolute path to the repository root + * @return number of files generated across all targets + */ + fun generate(repoRoot: Path): Int { + require(referenceSourceRoot.exists()) { + "Reference source root does not exist: $referenceSourceRoot" + } + + var totalGenerated = 0 + + for (target in targets) { + totalGenerated += generateTarget(repoRoot, target) + } + + return totalGenerated + } + + private fun generateTarget(repoRoot: Path, target: NmsVersionConfig): Int { + val targetSourceRoot = repoRoot.resolve(target.sourceModulePath) + .resolve("src/main/kotlin") + + // Clean existing generated sources + if (targetSourceRoot.exists()) { + targetSourceRoot.toFile().deleteRecursively() + } + targetSourceRoot.createDirectories() + + val sourceFiles = referenceSourceRoot.toFile() + .walk() + .filter { it.isFile && it.extension == "kt" } + .toList() + + var generated = 0 + + for (sourceFile in sourceFiles) { + val relativePath = referenceSourceRoot.relativize(sourceFile.toPath()) + val transformedRelativePath = transformPath(relativePath, target) + val targetFile = targetSourceRoot.resolve(transformedRelativePath) + targetFile.parent.createDirectories() + + val originalContent = sourceFile.readText() + val relativeKey = relativePath.toString().replace('\\', '/') + val transformedContent = transformContent(originalContent, target, relativeKey) + + targetFile.writeText(transformedContent) + generated++ + } + + println("Generated $generated files for ${target.versionId} in ${targetSourceRoot.toAbsolutePath()}") + return generated + } + + /** + * Transforms a relative path from the reference module to the target module. + * Replaces the reference package directory segments with target ones. + */ + private fun transformPath(relativePath: Path, target: NmsVersionConfig): Path { + val pathStr = relativePath.toString().replace('\\', '/') + val transformed = pathStr + .replace(referenceVersionId, target.versionId) + .replace(referenceClassPrefix, target.classPrefix) + return Path(transformed) + } + + /** + * Transforms file content from reference version to target version. + */ + private fun transformContent( + content: String, + target: NmsVersionConfig, + relativeKey: String, + ): String { + var result = content + + // 1. Replace package names (reference version → target version) + result = result.replace(referenceVersionId, target.versionId) + + // 2. Replace class prefixes (e.g. V26_1 → V1_21_11) + result = result.replace(referenceClassPrefix, target.classPrefix) + + // 3. Apply import-level replacements + for ((old, new) in target.importReplacements) { + result = result.replace(old, new) + } + + // 4. Apply code-level replacements + for ((old, new) in target.codeReplacements) { + result = result.replace(old, new) + } + + // 5. Apply per-file custom transformers + val transformer = target.fileTransformers[relativeKey] + if (transformer != null) { + result = transformer(result) + } + + return result + } +} diff --git a/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsVersionConfig.kt b/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsVersionConfig.kt new file mode 100644 index 000000000..9c7649df3 --- /dev/null +++ b/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsVersionConfig.kt @@ -0,0 +1,20 @@ +package dev.slne.surf.api.gen.nms + +/** + * Configuration for a target NMS version. + * + * @property versionId Short identifier used in package/class names, e.g. "v1_21_11" + * @property classPrefix Prefix for generated class names, e.g. "V1_21_11" + * @property sourceModulePath Relative path from repo root to the target module's source root + * @property importReplacements Map of import replacements (old → new) applied to every file + * @property codeReplacements Map of code-level string replacements applied after import replacement + * @property fileTransformers Per-file transformers keyed by relative source path (from the reference module) + */ +data class NmsVersionConfig( + val versionId: String, + val classPrefix: String, + val sourceModulePath: String, + val importReplacements: Map = emptyMap(), + val codeReplacements: Map = emptyMap(), + val fileTransformers: Map String> = emptyMap(), +) diff --git a/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsVersionConfigs.kt b/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsVersionConfigs.kt new file mode 100644 index 000000000..d02540635 --- /dev/null +++ b/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsVersionConfigs.kt @@ -0,0 +1,80 @@ +package dev.slne.surf.api.gen.nms + +/** + * Registry of all NMS version configurations. + * + * The **reference version** is v26_1 (Paper 26.1+). All other versions are + * generated by transforming the reference sources. + * + * To add a new Minecraft version: + * 1. Add an [NmsVersionConfig] entry here + * 2. Create the Gradle module (build.gradle.kts with correct paperweight dev-bundle) + * 3. Register the module in settings.gradle.kts + * 4. Re-run the generator: `./gradlew :surf-api-generator:generateNms` + */ +object NmsVersionConfigs { + + /** Reference version identifiers (source of truth). */ + const val REFERENCE_VERSION_ID = "v26_1" + const val REFERENCE_CLASS_PREFIX = "V26_1" + const val REFERENCE_MODULE_PATH = "surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1" + + /** + * NMS version config for Minecraft 1.21.11 (Canvas). + * + * Key differences from 26.1: + * - `net.minecraft.resources.Identifier` → `net.minecraft.resources.ResourceLocation` + * - `Identifier.fromNamespaceAndPath(...)` → `ResourceLocation.fromNamespaceAndPath(...)` + * - `ClientboundClearDialogPacket` does not exist → clearDialogs becomes a no-op + * - `player.showDialog(...)` does not exist → removed + * - `noticeDialogWithBuilder` import does not exist → removed + * - `TypedEntityData` does not exist → use `CustomData.of(...)` instead + */ + val V1_21_11 = NmsVersionConfig( + versionId = "v1_21_11", + classPrefix = "V1_21_11", + sourceModulePath = "surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11", + importReplacements = mapOf( + "import net.minecraft.resources.Identifier" to "import net.minecraft.resources.ResourceLocation", + "import net.minecraft.world.item.component.TypedEntityData\n" to "", + ), + codeReplacements = mapOf( + // Identifier class → ResourceLocation + "Identifier.fromNamespaceAndPath(" to "ResourceLocation.fromNamespaceAndPath(", + // Type references in function signatures + "id: Identifier" to "id: ResourceLocation", + "(id: Identifier," to "(id: ResourceLocation,", + "fun showPacket(id: Identifier," to "fun showPacket(id: ResourceLocation,", + "fun hidePacket(id: Identifier)" to "fun hidePacket(id: ResourceLocation)", + "fun createAdvancement(id: Identifier," to "fun createAdvancement(id: ResourceLocation,", + // TypedEntityData → CustomData.of + "TypedEntityData.decodeEntity(nbt)" to "CustomData.of(nbt)", + ), + fileTransformers = mapOf( + // The CommonBridge needs special handling for clearDialogs (no dialog support in 1.21.11) + "dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsCommonBridgeImpl.kt" to { content -> + content + // Remove dialog-related imports + .replace("import dev.slne.surf.api.paper.dialog.noticeDialogWithBuilder\n", "") + .replace("import net.minecraft.network.protocol.common.ClientboundClearDialogPacket\n", "") + .replace("import net.kyori.adventure.text.Component\n", "") + // Replace clearDialogs implementation with no-op + .replace( + """ override fun clearDialogs(player: Player, showEmptyDialogBefore: Boolean) { + if (showEmptyDialogBefore) { + player.showDialog(noticeDialogWithBuilder(Component.empty()) {}) + } + + player.toNms().connection.send(ClientboundClearDialogPacket.INSTANCE) + }""", + """ override fun clearDialogs(player: Player, showEmptyDialogBefore: Boolean) { + // Dialogs are not supported in 1.21.11 + }""" + ) + }, + ), + ) + + /** All target versions that should be generated from the reference. */ + val ALL_TARGETS = listOf(V1_21_11) +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsPacketBridgeHandler.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsPacketBridgeHandler.kt new file mode 100644 index 000000000..d812cebbf --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsPacketBridgeHandler.kt @@ -0,0 +1,28 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11 + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.common.NmsPacketBridgeHandler +import dev.slne.surf.api.paper.nms.listener.packets.NmsPacket +import dev.slne.surf.api.paper.nms.listener.packets.clientbound.NmsClientboundPacket +import dev.slne.surf.api.paper.nms.listener.packets.serverbound.NmsServerboundPacket +import dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.V1_21_11NmsPacketImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.V1_21_11PacketRegistry +import net.minecraft.network.protocol.Packet + +@NmsUseWithCaution +class V1_21_11NmsPacketBridgeHandler : NmsPacketBridgeHandler { + + @Suppress("UNCHECKED_CAST") + override fun wrapServerboundPacket(nmsPacket: Any): NmsServerboundPacket? { + return V1_21_11PacketRegistry.createServerboundPacketOrNull(nmsPacket as Packet<*>) + } + + @Suppress("UNCHECKED_CAST") + override fun wrapClientboundPacket(nmsPacket: Any): NmsClientboundPacket? { + return V1_21_11PacketRegistry.createClientboundPacketOrNull(nmsPacket as Packet<*>) + } + + override fun unwrapPacket(apiPacket: NmsPacket): Any { + return V1_21_11NmsPacketImpl.getFromApi(apiPacket).nmsPacket + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt index 6dce0bc4a..12f65513c 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt @@ -17,83 +17,62 @@ import dev.slne.surf.api.paper.nms.common.NmsVersion import dev.slne.surf.api.paper.nms.common.PacketLoreRegistry import dev.slne.surf.api.paper.packet.listener.listener.PacketListener import dev.slne.surf.api.paper.region.TickThreadGuard +import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.* +import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.V1_21_11SurfPaperNmsPacketBridgesImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.block.V1_21_11SurfPaperNmsBlockPacketsImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.entity.V1_21_11SurfPaperNmsSpawnPacketsImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.player.V1_21_11SurfPaperNmsPlayerChatPacketsImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.player.V1_21_11SurfPaperNmsPlayerPacketsImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.player.V1_21_11SurfPaperNmsPlayerToastPacketsImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.V1_21_11GlowingLifecycleHandler +import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.V1_21_11SurfGlowingApiImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.packet.listener.V1_21_11GlowingPacketListener +import dev.slne.surf.api.paper.server.nms.v1_21_11.packet.lore.V1_21_11PacketLoreListener +import dev.slne.surf.api.paper.server.nms.v1_21_11.packet.lore.V1_21_11PacketLoreRegistry +import dev.slne.surf.api.paper.server.nms.v1_21_11.reflection.V1_21_11Reflection +import dev.slne.surf.api.paper.server.nms.v1_21_11.region.V1_21_11TickThreadGuard +import org.bukkit.plugin.java.JavaPlugin -/** - * NMS provider for Minecraft 1.21.11. - * - * TODO: Implement all methods with 1.21.11-specific NMS code. - * Each method should return an implementation adapted for the 1.21.11 NMS API. - * Use the V26_1 implementations as a reference and adapt for API differences. - */ @AutoService(NmsProvider::class) class V1_21_11NmsProvider : NmsProvider { override val version: NmsVersion = NmsVersion.V1_21_11 - override fun createNmsBridge(): SurfPaperNmsBridge = - TODO("Implement SurfPaperNmsBridge for 1.21.11") - - override fun createCommonBridge(): SurfPaperNmsCommonBridge = - TODO("Implement SurfPaperNmsCommonBridge for 1.21.11") - - override fun createEntityBridge(): SurfPaperNmsEntityBridge = - TODO("Implement SurfPaperNmsEntityBridge for 1.21.11") - - override fun createItemBridge(): SurfPaperNmsItemBridge = - TODO("Implement SurfPaperNmsItemBridge for 1.21.11") - - override fun createNbtBridge(): SurfPaperNmsNbtBridge = - TODO("Implement SurfPaperNmsNbtBridge for 1.21.11") - - override fun createGlowingBridge(): SurfPaperNmsGlowingBridge = - TODO("Implement SurfPaperNmsGlowingBridge for 1.21.11") - - override fun createStatsBridge(): SurfPaperNmsStatsBridge = - TODO("Implement SurfPaperNmsStatsBridge for 1.21.11") - - override fun createLootTableBridge(): SurfPaperNmsLootTableBridge = - TODO("Implement SurfPaperNmsLootTableBridge for 1.21.11") - - override fun createCommandArgumentTypesBridge(): SurfPaperNmsCommandArgumentTypesBridge = - TODO("Implement SurfPaperNmsCommandArgumentTypesBridge for 1.21.11") - - override fun createPacketBridges(): SurfPaperNmsPacketBridges = - TODO("Implement SurfPaperNmsPacketBridges for 1.21.11") - - override fun createBlockPackets(): SurfPaperNmsBlockPackets = - TODO("Implement SurfPaperNmsBlockPackets for 1.21.11") - - override fun createSpawnPackets(): SurfPaperNmsSpawnPackets = - TODO("Implement SurfPaperNmsSpawnPackets for 1.21.11") - - override fun createPlayerPackets(): SurfPaperNmsPlayerPackets = - TODO("Implement SurfPaperNmsPlayerPackets for 1.21.11") - - override fun createPlayerChatPackets(): SurfPaperNmsPlayerChatPackets = - TODO("Implement SurfPaperNmsPlayerChatPackets for 1.21.11") - - override fun createPlayerToastPackets(): SurfPaperNmsPlayerToastPackets = - TODO("Implement SurfPaperNmsPlayerToastPackets for 1.21.11") - - override fun createTickThreadGuard(): TickThreadGuard = - TODO("Implement TickThreadGuard for 1.21.11") - - override fun createPacketBridgeHandler(): NmsPacketBridgeHandler = - TODO("Implement NmsPacketBridgeHandler for 1.21.11") - - override fun createPacketLoreRegistry(): PacketLoreRegistry = - TODO("Implement PacketLoreRegistry for 1.21.11") - - override fun createGlowingLifecycleHandler(): GlowingLifecycleHandler = - TODO("Implement GlowingLifecycleHandler for 1.21.11") - - override fun createGlowingApi(): SurfGlowingApi = - TODO("Implement SurfGlowingApi for 1.21.11") + private var glowingApi: V1_21_11SurfGlowingApiImpl? = null + + override fun createNmsBridge(): SurfPaperNmsBridge = V1_21_11SurfPaperNmsBridgeImpl() + override fun createCommonBridge(): SurfPaperNmsCommonBridge = V1_21_11SurfPaperNmsCommonBridgeImpl() + override fun createEntityBridge(): SurfPaperNmsEntityBridge = V1_21_11SurfPaperNmsEntityBridgeImpl() + override fun createItemBridge(): SurfPaperNmsItemBridge = V1_21_11SurfPaperNmsItemBridgeImpl() + override fun createNbtBridge(): SurfPaperNmsNbtBridge = V1_21_11SurfPaperNmsNbtBridgeImpl() + override fun createGlowingBridge(): SurfPaperNmsGlowingBridge = V1_21_11SurfPaperNmsGlowingBridgeImpl() + override fun createStatsBridge(): SurfPaperNmsStatsBridge = V1_21_11SurfPaperNmsStatsBridgeImpl() + override fun createLootTableBridge(): SurfPaperNmsLootTableBridge = V1_21_11SurfPaperNmsLootTableBridgeImpl() + override fun createCommandArgumentTypesBridge(): SurfPaperNmsCommandArgumentTypesBridge = V1_21_11SurfPaperNmsCommandArgumentTypesBridgeImpl() + override fun createPacketBridges(): SurfPaperNmsPacketBridges = V1_21_11SurfPaperNmsPacketBridgesImpl() + override fun createBlockPackets(): SurfPaperNmsBlockPackets = V1_21_11SurfPaperNmsBlockPacketsImpl() + override fun createSpawnPackets(): SurfPaperNmsSpawnPackets = V1_21_11SurfPaperNmsSpawnPacketsImpl() + override fun createPlayerPackets(): SurfPaperNmsPlayerPackets = V1_21_11SurfPaperNmsPlayerPacketsImpl() + override fun createPlayerChatPackets(): SurfPaperNmsPlayerChatPackets = V1_21_11SurfPaperNmsPlayerChatPacketsImpl() + override fun createPlayerToastPackets(): SurfPaperNmsPlayerToastPackets = V1_21_11SurfPaperNmsPlayerToastPacketsImpl() + override fun createTickThreadGuard(): TickThreadGuard = V1_21_11TickThreadGuard() + override fun createPacketBridgeHandler(): NmsPacketBridgeHandler = V1_21_11NmsPacketBridgeHandler() + override fun createPacketLoreRegistry(): PacketLoreRegistry = V1_21_11PacketLoreRegistry() + override fun createGlowingLifecycleHandler(): GlowingLifecycleHandler = V1_21_11GlowingLifecycleHandler() + + override fun createGlowingApi(): SurfGlowingApi { + val plugin = JavaPlugin.getProvidingPlugin(V1_21_11NmsProvider::class.java) as JavaPlugin + val api = V1_21_11SurfGlowingApiImpl(plugin) + glowingApi = api + return api + } - override fun createPacketListeners(): List = - TODO("Implement packet listeners for 1.21.11") + override fun createPacketListeners(): List = listOf( + V1_21_11PacketLoreListener, + V1_21_11GlowingPacketListener, + ) override fun initialize() { - TODO("Initialize 1.21.11 NMS resources") + V1_21_11Reflection.initialize() } override fun shutdown() { diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsBridgeImpl.kt new file mode 100644 index 000000000..e62fb4bd4 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsBridgeImpl.kt @@ -0,0 +1,128 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges + +import com.google.common.flogger.StackSize +import dev.slne.surf.api.core.util.logger +import dev.slne.surf.api.paper.api.nms.listener.NmsClientboundPacketListener +import dev.slne.surf.api.paper.api.nms.listener.NmsServerboundPacketListener +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge +import dev.slne.surf.api.paper.nms.listener.packets.clientbound.NmsClientboundPacket +import dev.slne.surf.api.paper.nms.listener.packets.serverbound.NmsServerboundPacket +import dev.slne.surf.api.paper.packet.listener.listener.PacketListenerResult +import dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.V1_21_11NmsPacketImpl +import org.bukkit.entity.Player +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.CopyOnWriteArraySet + +@NmsUseWithCaution +class V1_21_11SurfPaperNmsBridgeImpl : SurfPaperNmsBridge { + private val log = logger() + + private val serverboundPacketListeners = + ConcurrentHashMap, CopyOnWriteArraySet>>() + private val clientboundPacketListeners = + ConcurrentHashMap, CopyOnWriteArraySet>>() + + override fun registerServerboundPacketListener(listener: NmsServerboundPacketListener<*>) { + val packetClass = listener.packetClass + val added = + serverboundPacketListeners.computeIfAbsent(packetClass) { CopyOnWriteArraySet() } + .add(listener) + + if (!added) { + log.atWarning() + .withStackTrace(StackSize.MEDIUM) + .log("Serverbound packet listener $listener is already registered") + } + } + + override fun unregisterServerboundPacketListener(listener: NmsServerboundPacketListener<*>) { + val removed = serverboundPacketListeners[listener.packetClass]?.remove(listener) == true + + if (!removed) { + log.atWarning() + .withStackTrace(StackSize.MEDIUM) + .log("Serverbound packet listener $listener is not registered") + } + } + + override fun registerClientboundPacketListener(listener: NmsClientboundPacketListener<*>) { + val packetClass = listener.packetClass + val added = + clientboundPacketListeners.computeIfAbsent(packetClass) { CopyOnWriteArraySet() } + .add(listener) + + if (!added) { + log.atWarning() + .withStackTrace(StackSize.MEDIUM) + .log("Clientbound packet listener $listener is already registered") + } + } + + override fun unregisterClientboundPacketListener(listener: NmsClientboundPacketListener<*>) { + val removed = clientboundPacketListeners[listener.packetClass]?.remove(listener) == true + + if (!removed) { + log.atWarning() + .withStackTrace(StackSize.MEDIUM) + .log("Clientbound packet listener $listener is not registered") + } + } + + @Suppress("UNCHECKED_CAST") + fun handleServerboundPacket( + packet: Packet, + player: Player?, + ): Packet? { + val clazz = packet.packetClass + val listener = serverboundPacketListeners[clazz] ?: return packet + + var cancel = false + for (listener in listener) { + listener as NmsServerboundPacketListener + val result = try { + listener.handleEarlyServerboundPacket(packet, player) + } catch (e: Throwable) { + log.atSevere() + .withCause(e) + .log("Failed to handle serverbound packet $clazz for listener $listener") + PacketListenerResult.CONTINUE + } + + if (result == PacketListenerResult.CANCEL) { + cancel = true + } + } + + return if (cancel) null else packet + } + + @Suppress("UNCHECKED_CAST") + fun handleClientboundPacket( + packet: Packet, + player: Player?, + ): Packet? { + val listeners = clientboundPacketListeners[packet.packetClass] ?: return packet + + if (listeners.isEmpty()) return packet + + var cancel = false + for (listener in listeners) { + listener as NmsClientboundPacketListener + val result = try { + listener.handleEarlyClientboundPacket(packet, player) + } catch (e: Throwable) { + log.atSevere() + .withCause(e) + .log("Failed to handle clientbound packet ${packet.packetClass} for listener $listener") + PacketListenerResult.CONTINUE + } + + if (result == PacketListenerResult.CANCEL) { + cancel = true + } + } + + return if (cancel) null else packet + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsCommandArgumentTypesBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsCommandArgumentTypesBridgeImpl.kt new file mode 100644 index 000000000..86d6964de --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsCommandArgumentTypesBridgeImpl.kt @@ -0,0 +1,107 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges + +import com.mojang.brigadier.arguments.ArgumentType +import com.mojang.brigadier.context.CommandContext +import com.mojang.brigadier.exceptions.CommandSyntaxException +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsCommandArgumentTypesBridge +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.AdventureNBT +import dev.slne.surf.api.paper.server.nms.v1_21_11.reflection.V1_21_11Reflection +import net.bytebuddy.ByteBuddy +import net.bytebuddy.dynamic.loading.ClassLoadingStrategy +import net.bytebuddy.dynamic.scaffold.TypeValidation +import net.bytebuddy.implementation.InvocationHandlerAdapter +import net.bytebuddy.implementation.bind.annotation.RuntimeType +import net.bytebuddy.matcher.ElementMatchers +import net.kyori.adventure.nbt.CompoundBinaryTag +import net.minecraft.commands.arguments.CompoundTagArgument +import java.lang.reflect.InvocationHandler +import java.util.concurrent.ConcurrentHashMap + +@NmsUseWithCaution +class V1_21_11SurfPaperNmsCommandArgumentTypesBridgeImpl : SurfPaperNmsCommandArgumentTypesBridge { + + override fun compoundTag(): ArgumentType<*> { + return CompoundTagArgument.compoundTag() + } + + override fun getCompoundTag(ctx: CommandContext<*>, key: String): CompoundBinaryTag { + val nms = CompoundTagArgument.getCompoundTag(ctx, key) + return AdventureNBT.fromNms(nms) + } + + @Suppress("UNCHECKED_CAST") + private fun wrap( + base: ArgumentType, + converter: OpenedResultConverter + ): ArgumentType { + val wrappedConverter = OpenedResultConverterImpl.of(converter) + val wrapped = V1_21_11Reflection.VANILLA_ARGUMENT_PROVIDER_IMPL_PROXY.wrap( + V1_21_11Reflection.VANILLA_ARGUMENT_PROVIDER_PROXY.provider(), + base, + wrappedConverter + ) as ArgumentType + + return wrapped + } + + + fun interface OpenedResultConverter { + @Throws(CommandSyntaxException::class) + fun convert(type: T): R + } + + object OpenedResultConverterImpl { + private val converterCache = ConcurrentHashMap() + + @Suppress("UNCHECKED_CAST") + fun of(converter: OpenedResultConverter): Any { + val cacheKey = "${converter.javaClass.name}_${System.identityHashCode(converter)}" + + return converterCache.computeIfAbsent(cacheKey) { + createConverter(converter) + } + } + + @Suppress("UNCHECKED_CAST") + private fun createConverter(converter: OpenedResultConverter): Any { + val resultConverterInterface = Class.forName( + "io.papermc.paper.command.brigadier.argument.VanillaArgumentProviderImpl\$ResultConverter" + ) + + val handler = InvocationHandler { _, method, args -> + when (method.name) { + "convert" -> converter.convert(args[0] as B) + else -> throw UnsupportedOperationException("Unknown method: ${method.name}") + } + } + + val dynamicType = ByteBuddy() + .with(TypeValidation.DISABLED) + .subclass(Any::class.java) + .implement(resultConverterInterface) + .name("io.papermc.paper.command.brigadier.argument.GeneratedResultConverter\$${System.nanoTime()}") + .method(ElementMatchers.any()) + .intercept(InvocationHandlerAdapter.of(handler)) + .make() + + val loadedClass = dynamicType.load( + resultConverterInterface.classLoader, + ClassLoadingStrategy.Default.INJECTION + ).loaded + + return loadedClass.getDeclaredConstructor().newInstance() + } + + + class InterceptorHolder( + private val converter: OpenedResultConverter + ) { + @RuntimeType + @Throws(Exception::class) + fun convert(@RuntimeType input: B): C { + return converter.convert(input) + } + } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsCommonBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsCommonBridgeImpl.kt new file mode 100644 index 000000000..e1552d58b --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsCommonBridgeImpl.kt @@ -0,0 +1,83 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsCommonBridge +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNms +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNmsBlock +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNmsItem +import dev.slne.surf.api.paper.server.nms.v1_21_11.reflection.V1_21_11Reflection +import io.papermc.paper.configuration.GlobalConfiguration +import net.minecraft.server.MinecraftServer +import net.minecraft.world.level.block.Block +import net.minecraft.world.level.block.ComposterBlock +import org.bukkit.Bukkit +import org.bukkit.Material +import org.bukkit.block.data.BlockData +import org.bukkit.entity.Player +import java.net.InetSocketAddress + +@NmsUseWithCaution +class V1_21_11SurfPaperNmsCommonBridgeImpl : SurfPaperNmsCommonBridge { + + @Suppress("DEPRECATION") + override fun nextEntityId(): Int { + return Bukkit.getUnsafe().nextEntityId() + } + + override fun getStateId(material: Material): Int { + return Block.getId(material.toNmsBlock().defaultBlockState()) + } + + override fun getStateId(blockData: BlockData): Int { + return Block.getId(blockData.toNms()) + } + + override fun generateNextInventoryId(player: Player): Int { + return player.toNms().nextContainerCounter() + } + + override fun addCompostable(material: Material, levelIncreaseChance: Float) { + require(material.isItem) { "material must be an item" } + + ComposterBlock.COMPOSTABLES.put(material.toNmsItem(), levelIncreaseChance) + } + + override fun removeCompostable(material: Material) { + require(material.isItem) { "material must be an item" } + ComposterBlock.COMPOSTABLES.removeFloat(material.toNmsItem()) + } + + override fun setVelocityEnabled(enabled: Boolean) { + GlobalConfiguration.get().proxies.velocity.enabled = enabled + } + + override fun isVelocityEnabled(): Boolean { + return GlobalConfiguration.get().proxies.velocity.enabled + } + + override fun setVelocitySecret(secret: String) { + GlobalConfiguration.get().proxies.velocity.secret = secret + } + + override fun getVelocitySecret(): String { + return GlobalConfiguration.get().proxies.velocity.secret + } + + override fun setOnlineMode(enabled: Boolean) { + MinecraftServer.getServer().setUsesAuthentication(enabled) + } + + override fun clearDialogs(player: Player, showEmptyDialogBefore: Boolean) { + // Dialogs are not supported in 1.21.11 + } + + override fun getServerIp(): InetSocketAddress { + val channels = + V1_21_11Reflection.SERVER_CONNECTION_LISTENER_PROXY.getChannels(MinecraftServer.getServer().connection) + val channel = + channels.firstOrNull() ?: error("No channels found in server connection listener proxy") + + return channel.channel().localAddress() as? InetSocketAddress + ?: error("Local address is not an instance of InetSocketAddress") + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsEntityBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsEntityBridgeImpl.kt new file mode 100644 index 000000000..aafcd14a0 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsEntityBridgeImpl.kt @@ -0,0 +1,53 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges + +import ca.spottedleaf.moonrise.common.util.TickThread +import com.mojang.brigadier.exceptions.CommandSyntaxException +import dev.jorel.commandapi.exceptions.WrapperCommandSyntaxException +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsEntityBridge +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.AdventureNBT +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNms +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNmsHolder +import dev.slne.surf.api.paper.util.chunkX +import dev.slne.surf.api.paper.util.chunkZ +import io.papermc.paper.math.FinePosition +import net.kyori.adventure.nbt.CompoundBinaryTag +import net.minecraft.server.MinecraftServer +import net.minecraft.server.commands.SummonCommand +import org.bukkit.World +import org.bukkit.entity.EntityType + +@NmsUseWithCaution +class V1_21_11SurfPaperNmsEntityBridgeImpl : SurfPaperNmsEntityBridge { + + @Suppress("UnstableApiUsage") + override fun createEntityByNbt( + world: World, + type: EntityType, + pos: FinePosition, + tag: CompoundBinaryTag + ) { + val worldNMS = world.toNms() + TickThread.ensureTickThread( + worldNMS, + pos.chunkX, + pos.chunkZ, + "Cannot create entity asynchronously" + ) + + val source = MinecraftServer.getServer().createCommandSourceStack() + .withLevel(worldNMS) + + try { + SummonCommand.createEntity( + source, + type.toNmsHolder(), + pos.toNms(), + AdventureNBT.toNms(tag), + false + ) + } catch (e: CommandSyntaxException) { + throw WrapperCommandSyntaxException(e) + } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsGlowingBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsGlowingBridgeImpl.kt new file mode 100644 index 000000000..81b39f348 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsGlowingBridgeImpl.kt @@ -0,0 +1,60 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsGlowingBridge +import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation +import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.V1_21_11PacketOperationImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNms +import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.V1_21_11TeamData +import dev.slne.surf.api.paper.server.nms.v1_21_11.packet.listener.V1_21_11GlowingPacketListener +import dev.slne.surf.api.paper.server.nms.v1_21_11.reflection.V1_21_11Reflection +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket +import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket +import net.minecraft.network.syncher.SynchedEntityData.DataValue +import org.bukkit.entity.Entity + +@NmsUseWithCaution +class V1_21_11SurfPaperNmsGlowingBridgeImpl : SurfPaperNmsGlowingBridge { + fun createTeam(data: V1_21_11TeamData): PacketOperation = + V1_21_11PacketOperationImpl.simple { + ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(data.team, true) + } + + fun addEntityToTeam(data: V1_21_11TeamData, entry: String): PacketOperation = + V1_21_11PacketOperationImpl.simple { + ClientboundSetPlayerTeamPacket.createPlayerPacket( + data.team, + entry, + ClientboundSetPlayerTeamPacket.Action.ADD + ) + } + + fun removeEntityFromTeam(data: V1_21_11TeamData, entry: String): PacketOperation = + V1_21_11PacketOperationImpl.simple { + ClientboundSetPlayerTeamPacket.createPlayerPacket( + data.team, + entry, + ClientboundSetPlayerTeamPacket.Action.REMOVE + ) + } + + fun setEntityFlags(entityId: Int, flags: Byte, ignorePacket: Boolean = false): PacketOperation = + V1_21_11PacketOperationImpl.simple { + val dataAccessor = V1_21_11Reflection.ENTITY_PROXY.getDataFlagsSharedId() + val data = DataValue(dataAccessor.id(), dataAccessor.serializer, flags) + ClientboundSetEntityDataPacket(entityId, listOf(data)).also { + if (ignorePacket) { + V1_21_11GlowingPacketListener.ignorePacket(it) + } + } + } + + override fun getCurrentFlags(entity: Entity): Byte { + val dataAccessor = V1_21_11Reflection.ENTITY_PROXY.getDataFlagsSharedId() + return entity.toNms().entityData.get(dataAccessor) + } + + companion object { + val INSTANCE get() = SurfPaperNmsGlowingBridge.INSTANCE as V1_21_11SurfPaperNmsGlowingBridgeImpl + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsItemBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsItemBridgeImpl.kt new file mode 100644 index 000000000..e1bdfc4e9 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsItemBridgeImpl.kt @@ -0,0 +1,24 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsItemBridge +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.nms +import net.minecraft.core.component.DataComponentMap +import net.minecraft.core.component.DataComponents +import org.bukkit.inventory.ItemType + +@NmsUseWithCaution +class V1_21_11SurfPaperNmsItemBridgeImpl : SurfPaperNmsItemBridge { + + override fun setDefaultMaxStackSize(item: ItemType, maxStackSize: Int) { + require(maxStackSize in 1..100) { "Max stack size must be between 1 and 100" } + + val nmsItem = item.nms + val updatedComponents = DataComponentMap.builder() + .addAll(nmsItem.components()) + .set(DataComponents.MAX_STACK_SIZE, maxStackSize) + .build() + + nmsItem.builtInRegistryHolder().bindComponents(updatedComponents) + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsLootTableBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsLootTableBridgeImpl.kt new file mode 100644 index 000000000..df9a5041a --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsLootTableBridgeImpl.kt @@ -0,0 +1,55 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges + +import dev.slne.surf.api.core.util.emptyObjectList +import dev.slne.surf.api.core.util.mutableObjectListOf +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsLootTableBridge +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toBukkit +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNms +import net.minecraft.server.MinecraftServer +import net.minecraft.server.level.ServerLevel +import net.minecraft.world.level.storage.loot.LootParams +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets +import net.minecraft.world.level.storage.loot.parameters.LootContextParams +import org.bukkit.damage.DamageSource +import org.bukkit.entity.EntityType +import org.bukkit.entity.LivingEntity +import org.bukkit.inventory.ItemStack +import kotlin.jvm.optionals.getOrNull + +@NmsUseWithCaution +class V1_21_11SurfPaperNmsLootTableBridgeImpl : SurfPaperNmsLootTableBridge { + override fun getDifferentLootTable( + entity: LivingEntity, + damageSource: DamageSource, + replacement: EntityType, + causedByPlayer: Boolean, + ): Collection { + val lootTableKey = + replacement.toNms().defaultLootTable.getOrNull() ?: return emptyObjectList() + val lootTable = + MinecraftServer.getServer().reloadableRegistries().getLootTable(lootTableKey) + val nmsEntity = entity.toNms() + val nmsDamageSource = damageSource.toNms() + + val lootParamsBuilder = LootParams.Builder(nmsEntity.level() as ServerLevel) + .withParameter(LootContextParams.THIS_ENTITY, nmsEntity) + .withParameter(LootContextParams.ORIGIN, nmsEntity.position()) + .withParameter(LootContextParams.DAMAGE_SOURCE, nmsDamageSource) + .withOptionalParameter(LootContextParams.ATTACKING_ENTITY, nmsDamageSource.entity) + .withOptionalParameter( + LootContextParams.DIRECT_ATTACKING_ENTITY, + nmsDamageSource.directEntity + ) + + val lastHurtByPlayer = nmsEntity.getLastHurtByPlayer() + if (causedByPlayer && lastHurtByPlayer != null) { + lootParamsBuilder.withParameter(LootContextParams.LAST_DAMAGE_PLAYER, lastHurtByPlayer) + .withLuck(lastHurtByPlayer.luck) + } + + val lootParams = lootParamsBuilder.create(LootContextParamSets.ENTITY) + return lootTable.getRandomItems(lootParams, nmsEntity.lootTableSeed) + .mapTo(mutableObjectListOf()) { it.toBukkit() } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsNbtBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsNbtBridgeImpl.kt new file mode 100644 index 000000000..f311be643 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsNbtBridgeImpl.kt @@ -0,0 +1,62 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges + +import dev.slne.surf.api.core.util.logger +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsNbtBridge +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toBukkit +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNms +import net.minecraft.core.component.DataComponentPatch +import net.minecraft.core.component.DataComponents +import net.minecraft.nbt.CompoundTag +import net.minecraft.world.item.component.CustomData +import org.bukkit.entity.EntityType +import org.bukkit.inventory.ItemStack +import kotlin.jvm.optionals.getOrNull + +@NmsUseWithCaution +class V1_21_11SurfPaperNmsNbtBridgeImpl : SurfPaperNmsNbtBridge { + + private val log = logger() + + override fun makeItemStackEntityInvisible( + itemStack: ItemStack, + invisibleEntityType: EntityType, + ): ItemStack { + val nmsStack = itemStack.toNms() + + val nbt = CompoundTag() + nbt.putBoolean("Invisible", true) + nbt.putString("id", invisibleEntityType.key.asString()) + + val entityData = CustomData.of(nbt) + + val patch = DataComponentPatch.builder() + .set(DataComponents.ENTITY_DATA, entityData) + .build() + + nmsStack.applyComponents(patch) + + return nmsStack.toBukkit() + } + + @Suppress("OVERRIDE_DEPRECATION", "DEPRECATION") + override fun getNbtString( + itemStack: ItemStack, + key: String, + ): String { + log.atWarning() + .atMostEvery(30, java.util.concurrent.TimeUnit.SECONDS) + .log( + ("Using deprecated method getNbtString(ItemStack, String) in SurfBukkitNmsNbtBridgeImpl." + + " ItemStacks now use DataComponents and nbt keys are not used. Please update your" + + " code to use DataComponents instead.") + ) + + return itemStack.toNms().components + .getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY) + .unsafe + .getString(key) + .getOrNull() + ?: "{}" + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsStatsBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsStatsBridgeImpl.kt new file mode 100644 index 000000000..a18b4536e --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsStatsBridgeImpl.kt @@ -0,0 +1,21 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsStatsBridge +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNms +import dev.slne.surf.api.paper.server.nms.v1_21_11.reflection.V1_21_11Reflection +import org.bukkit.entity.Player + +@NmsUseWithCaution +class V1_21_11SurfPaperNmsStatsBridgeImpl : SurfPaperNmsStatsBridge { + + override fun getPlayerStatsAsJson(player: Player): String { + val gson = V1_21_11Reflection.SERVER_STATS_COUNTER_PROXY.getGson() + val jsonElement = V1_21_11Reflection.SERVER_STATS_COUNTER_PROXY.toJson(player.toNms().stats) + return gson.toJson(jsonElement) + } + + override fun savePlayerStatsToFile(player: Player) { + player.toNms().stats.save() + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/V1_21_11PacketOperationImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/V1_21_11PacketOperationImpl.kt new file mode 100644 index 000000000..9e00e2afd --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/V1_21_11PacketOperationImpl.kt @@ -0,0 +1,115 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets + +import com.google.common.flogger.FluentLogger +import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNms +import net.minecraft.network.protocol.Packet +import net.minecraft.network.protocol.game.ClientGamePacketListener +import net.minecraft.network.protocol.game.ClientboundBundlePacket +import org.bukkit.entity.Player +import java.util.* + +class V1_21_11PacketOperationImpl : PacketOperation { + private var operation: Operation + + private constructor(operation: Operation) { + this.operation = operation + } + + private constructor() { + this.operation = Operation.empty() + } + + override fun execute(player: Player) { + val connection = player.toNms().connection + val packets = operation.apply( + player, + LinkedList>() + ) + + if (packets.isEmpty()) { + return + } + + if (packets.size == 1) { + connection.send(packets.first()) + return + } + + connection.send(ClientboundBundlePacket(packets)) + } + + override fun add(operation: PacketOperation): V1_21_11PacketOperationImpl { + require(operation is V1_21_11PacketOperationImpl) { "operation must be an instance of V1_21_11PacketOperationImpl" } + + this.operation = this.operation.andThen(operation.operation) + return this + } + + override fun isEmpty(): Boolean { + val operation = operation + return operation is EmptyOperation && operation.empty + } + + fun interface Operation { + fun apply( + player: Player, + packets: LinkedList>, + ): LinkedList> + + fun andThen(after: Operation): Operation { + return Operation { player, packets -> + after.apply(player, apply(player, packets)) + } + } + + companion object { + fun empty() = EmptyOperation() + } + } + + class EmptyOperation : Operation { + var empty: Boolean = true + private set + + override fun apply( + player: Player, + packets: LinkedList>, + ): LinkedList> { + return packets + } + + override fun andThen(after: Operation): Operation { + empty = false + return super.andThen(after) + } + } + + companion object { + private val logger: FluentLogger = FluentLogger.forEnclosingClass() + + @JvmStatic + fun empty(): V1_21_11PacketOperationImpl { + return V1_21_11PacketOperationImpl() + } + + @JvmStatic + fun complex(operation: Operation): V1_21_11PacketOperationImpl { + return V1_21_11PacketOperationImpl(operation) + } + + fun simple(packetSupplier: (Player) -> Packet): V1_21_11PacketOperationImpl { + return V1_21_11PacketOperationImpl { player, packets -> + packets.add(packetSupplier(player)) + packets + } + } + + fun task(task: (Player) -> Unit): V1_21_11PacketOperationImpl { + return V1_21_11PacketOperationImpl { player, packets -> + task(player) + packets + } + } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/V1_21_11SurfPaperNmsPacketBridgesImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/V1_21_11SurfPaperNmsPacketBridgesImpl.kt new file mode 100644 index 000000000..2f248d5aa --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/V1_21_11SurfPaperNmsPacketBridgesImpl.kt @@ -0,0 +1,12 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.SurfPaperNmsPacketBridges + +@NmsUseWithCaution +class V1_21_11SurfPaperNmsPacketBridgesImpl : SurfPaperNmsPacketBridges { + + override fun createEmptyPacketOperation(): V1_21_11PacketOperationImpl { + return V1_21_11PacketOperationImpl.empty() + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/block/V1_21_11SurfPaperNmsBlockPacketsImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/block/V1_21_11SurfPaperNmsBlockPacketsImpl.kt new file mode 100644 index 000000000..d57ab8cbc --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/block/V1_21_11SurfPaperNmsBlockPacketsImpl.kt @@ -0,0 +1,31 @@ +@file:Suppress("UnstableApiUsage") + +package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.block + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.block.SurfPaperNmsBlockPackets +import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.V1_21_11PacketOperationImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNms +import io.papermc.paper.math.BlockPosition +import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket +import org.bukkit.block.data.BlockData + +@NmsUseWithCaution +class V1_21_11SurfPaperNmsBlockPacketsImpl : SurfPaperNmsBlockPackets { + + override fun updateBlockData(position: BlockPosition, blockData: BlockData) = + V1_21_11PacketOperationImpl.simple { + ClientboundBlockUpdatePacket( + position.toNms(), + blockData.toNms() + ) + } + + + override fun resetBlock(position: BlockPosition) = V1_21_11PacketOperationImpl.simple { + ClientboundBlockUpdatePacket( + it.toNms().level(), + position.toNms() + ) + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/entity/V1_21_11SurfPaperNmsSpawnPacketsImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/entity/V1_21_11SurfPaperNmsSpawnPacketsImpl.kt new file mode 100644 index 000000000..6a905e719 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/entity/V1_21_11SurfPaperNmsSpawnPacketsImpl.kt @@ -0,0 +1,207 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.entity + +import com.google.common.flogger.StackSize +import com.mojang.math.Transformation +import dev.slne.surf.api.core.util.logger +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.entity.* +import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.V1_21_11PacketOperationImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNms +import io.papermc.paper.math.BlockPosition +import io.papermc.paper.math.FinePosition +import it.unimi.dsi.fastutil.ints.IntList +import net.minecraft.core.HolderLookup +import net.minecraft.nbt.CompoundTag +import net.minecraft.nbt.NbtOps +import net.minecraft.network.protocol.game.* +import net.minecraft.server.MinecraftServer +import net.minecraft.world.entity.Display +import net.minecraft.world.entity.Entity +import net.minecraft.world.entity.EntityType +import net.minecraft.world.entity.PositionMoveRotation +import net.minecraft.world.level.block.entity.BlockEntityType +import net.minecraft.world.level.block.entity.SignText +import net.minecraft.world.phys.Vec3 +import org.bukkit.entity.TextDisplay.TextAlignment +import kotlin.experimental.and +import kotlin.experimental.inv +import kotlin.experimental.or + +@Suppress("UnstableApiUsage") +@NmsUseWithCaution +class V1_21_11SurfPaperNmsSpawnPacketsImpl : SurfPaperNmsSpawnPackets { + private val log = logger() + + override fun despawn(entityIds: IntList) = + V1_21_11PacketOperationImpl.simple { ClientboundRemoveEntitiesPacket(entityIds) } + + override fun despawn(vararg entityId: Int) = + V1_21_11PacketOperationImpl.simple { ClientboundRemoveEntitiesPacket(*entityId) } + + + override fun spawnItemDisplay( + entityId: Int, + position: FinePosition, + settings: ItemDisplaySettings, + ) = V1_21_11PacketOperationImpl.complex { player, packets -> + val serverPlayer = player.toNms() + val display = Display.ItemDisplay(EntityType.ITEM_DISPLAY, serverPlayer.level()).apply { + id = entityId + + setPosition(position) + applySettings(settings) + + itemStack = settings.itemStack.toNms() + itemTransform = settings.itemDisplayTransform.toNms() + } + + packets.add(ClientboundAddEntityPacket(display, 0, display.blockPosition())) + packets.add(createSetEntityDataPacket(entityId, display)) + packets + } + + override fun spawnTextDisplay( + entityId: Int, + position: FinePosition, + settings: TextDisplaySettings, + ) = V1_21_11PacketOperationImpl.complex { player, packets -> + val serverPlayer = player.toNms() + val display = Display.TextDisplay(EntityType.TEXT_DISPLAY, serverPlayer.level()).apply { + id = entityId + + setPosition(position) + applySettings(settings) + + text = settings.text.toNms() + + val data = getEntityData() + data[Display.TextDisplay.DATA_LINE_WIDTH_ID] = settings.lineWidth + data[Display.TextDisplay.DATA_BACKGROUND_COLOR_ID] = settings.backgroundColor.value() + + when (settings.textAlignment) { + TextAlignment.CENTER -> { + setFlag(Display.TextDisplay.FLAG_ALIGN_LEFT, false) + setFlag(Display.TextDisplay.FLAG_ALIGN_RIGHT, false) + } + + TextAlignment.LEFT -> { + setFlag(Display.TextDisplay.FLAG_ALIGN_LEFT, true) + setFlag(Display.TextDisplay.FLAG_ALIGN_RIGHT, false) + } + + TextAlignment.RIGHT -> { + setFlag(Display.TextDisplay.FLAG_ALIGN_LEFT, false) + setFlag(Display.TextDisplay.FLAG_ALIGN_RIGHT, true) + } + } + } + + + packets.add(ClientboundAddEntityPacket(display, 0, display.blockPosition())) + packets.add(createSetEntityDataPacket(entityId, display)) + packets + } + + override fun updateSign( + entityId: Int, + position: BlockPosition, + settings: SignBlockUpdateSettings, + ) = V1_21_11PacketOperationImpl.complex { player, packets -> + val nbt = CompoundTag() + val registryLookup = MinecraftServer.getServer().registryAccess() + writeUpdateSignToTag(nbt, registryLookup, settings.frontText, settings.backText) + + packets.add(ClientboundBlockEntityDataPacket(position.toNms(), BlockEntityType.SIGN, nbt)) + packets + } + + override fun spawnBlockDisplay( + entityId: Int, + position: FinePosition, + settings: BlockDisplaySettings, + ) = V1_21_11PacketOperationImpl.complex { player, packets -> + val serverPlayer = player.toNms() + val display = Display.BlockDisplay(EntityType.BLOCK_DISPLAY, serverPlayer.level()).apply { + id = entityId + + setPosition(position) + applySettings(settings) + blockState = settings.blockData.toNms() + } + + packets.add(ClientboundAddEntityPacket(display, 0, display.blockPosition())) + packets.add(createSetEntityDataPacket(entityId, display)) + packets + } + + override fun teleport( + entityId: Int, + position: FinePosition, + yaw: Float, + pitch: Float, + deltaMovement: FinePosition?, + onGround: Boolean, + ) = V1_21_11PacketOperationImpl.simple { + ClientboundTeleportEntityPacket.teleport( + entityId, + PositionMoveRotation(position.toNms(), deltaMovement?.toNms() ?: Vec3.ZERO, yaw, pitch), + emptySet(), + onGround + ) + } + + private fun createSetEntityDataPacket(entityId: Int, entity: Entity) = + ClientboundSetEntityDataPacket(entityId, entity.getEntityData().packAll()) + + private fun writeUpdateSignToTag( + nbt: CompoundTag, + registryLookup: HolderLookup.Provider, + frontText: SignBlockUpdateSettings.SignText, + backText: SignBlockUpdateSettings.SignText, + ) { + writeTextToTag(nbt, registryLookup, frontText, "front_text", true) + writeTextToTag(nbt, registryLookup, backText, "back_text", false) + } + + private fun writeTextToTag( + nbt: CompoundTag, + registryLookup: HolderLookup.Provider, + text: SignBlockUpdateSettings.SignText, + tagText: String, + isFrontText: Boolean, + ) { + val nbtOps = registryLookup.createSerializationContext(NbtOps.INSTANCE) + val textTag = SignText.DIRECT_CODEC.encodeStart(nbtOps, text.toNms()) + textTag.resultOrPartial { logFailedEncodeText(it, isFrontText) } + .ifPresent { nbt.put(tagText, it) } + } + + private fun logFailedEncodeText(string: String, front: Boolean) { + log.atSevere() + .withStackTrace(StackSize.MEDIUM) + .atMostEvery(5, java.util.concurrent.TimeUnit.SECONDS) + .log("Failed to encode %s text: %s", if (front) "front" else "back", string) + } + + private fun getTransformation(settings: DisplaySettings) = Transformation( + settings.translation.toNms(), + settings.leftRotation.toNms(), + settings.scale.toNms(), + settings.rightRotation.toNms() + ) + + private fun Display.applySettings(settings: DisplaySettings) { + xRot = settings.pitch + yRot = settings.yaw + setTransformation(getTransformation(settings)) + billboardConstraints = settings.billboardConstraints.toNms() + } + + private fun Entity.setPosition(position: FinePosition) { + setPosRaw(position.x(), position.y(), position.z()) + } + + private fun Display.TextDisplay.setFlag(flag: Byte, set: Boolean) { + flags = if (set) flags or flag else flags and flag.inv() + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/player/V1_21_11SurfPaperNmsPlayerChatPacketsImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/player/V1_21_11SurfPaperNmsPlayerChatPacketsImpl.kt new file mode 100644 index 000000000..5be4f1ebc --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/player/V1_21_11SurfPaperNmsPlayerChatPacketsImpl.kt @@ -0,0 +1,64 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.player + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation +import dev.slne.surf.api.paper.nms.bridges.packets.player.LastSeenMessagesPacked +import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerChatPackets +import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.V1_21_11PacketOperationImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNms +import net.kyori.adventure.chat.SignedMessage +import net.kyori.adventure.text.Component +import net.minecraft.network.chat.ChatType +import net.minecraft.network.chat.FilterMask +import net.minecraft.network.chat.LastSeenMessages +import net.minecraft.network.chat.SignedMessageBody +import net.minecraft.network.protocol.game.ClientboundPlayerChatPacket +import net.minecraft.server.MinecraftServer +import java.time.Instant +import java.util.* +import net.minecraft.network.chat.MessageSignature as NmsMessageSignature + +@NmsUseWithCaution +class V1_21_11SurfPaperNmsPlayerChatPacketsImpl : SurfPaperNmsPlayerChatPackets { + override fun sendPlayerChatMessagePacket( + senderUuid: UUID, + senderDisplayName: Component, + globalIndex: Int, + index: Int, + signature: SignedMessage.Signature?, + salt: Long, + timestamp: Instant, + content: String, + unsignedContent: Component?, + lastSeen: LastSeenMessagesPacked, + ): PacketOperation = V1_21_11PacketOperationImpl.simple { player -> + val messageSignature = signature?.let { NmsMessageSignature(it.bytes()) } + val signedBody = SignedMessageBody.Packed(content, timestamp, salt, lastSeen.toNms()) + + ClientboundPlayerChatPacket( + globalIndex, + senderUuid, + index, + messageSignature, + signedBody, + unsignedContent?.toNms(), + FilterMask.PASS_THROUGH, + ChatType.bind( + ChatType.CHAT, + MinecraftServer.getServer().registryAccess(), + senderDisplayName.toNms() + ) + ) + } + + private fun LastSeenMessagesPacked.toNms(): LastSeenMessages.Packed { + val list = mutableListOf() + + for ((id, signature) in this) { + val nmsSignature = signature?.let { NmsMessageSignature(it.bytes()) } + list.add(NmsMessageSignature.Packed(id, nmsSignature)) + } + + return LastSeenMessages.Packed(list) + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/player/V1_21_11SurfPaperNmsPlayerPacketsImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/player/V1_21_11SurfPaperNmsPlayerPacketsImpl.kt new file mode 100644 index 000000000..4314e873a --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/player/V1_21_11SurfPaperNmsPlayerPacketsImpl.kt @@ -0,0 +1,54 @@ +@file:Suppress("UnstableApiUsage") + +package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.player + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerPackets +import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.V1_21_11PacketOperationImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNms +import io.papermc.paper.math.BlockPosition +import net.kyori.adventure.text.Component +import net.minecraft.network.protocol.game.ClientboundContainerClosePacket +import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket +import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket +import net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket +import org.bukkit.event.inventory.InventoryType +import org.bukkit.inventory.ItemStack + +@NmsUseWithCaution +class V1_21_11SurfPaperNmsPlayerPacketsImpl : SurfPaperNmsPlayerPackets { + + override fun openSignEditor( + position: BlockPosition, + frontSide: Boolean, + ) = V1_21_11PacketOperationImpl.simple { ClientboundOpenSignEditorPacket(position.toNms(), frontSide) } + + override fun openInventory( + syncId: Int, + type: InventoryType, + title: Component, + ) = V1_21_11PacketOperationImpl.simple { + ClientboundOpenScreenPacket( + syncId, + type.toNms(), + title.toNms() + ) + } + + override fun setInventorySlot( + syncId: Int, + revision: Int, + slot: Int, + item: ItemStack, + ) = V1_21_11PacketOperationImpl.simple { + ClientboundContainerSetSlotPacket( + syncId, + revision, + slot, + item.toNms() + ) + } + + override fun closeInventory(syncId: Int) = + V1_21_11PacketOperationImpl.simple { ClientboundContainerClosePacket(syncId) } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/player/V1_21_11SurfPaperNmsPlayerToastPacketsImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/player/V1_21_11SurfPaperNmsPlayerToastPacketsImpl.kt new file mode 100644 index 000000000..0f4f36950 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/player/V1_21_11SurfPaperNmsPlayerToastPacketsImpl.kt @@ -0,0 +1,60 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.player + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToastPackets +import dev.slne.surf.api.paper.nms.bridges.packets.player.toast.Toast +import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.V1_21_11PacketOperationImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNms +import net.minecraft.advancements.Advancement +import net.minecraft.advancements.AdvancementProgress +import net.minecraft.advancements.AdvancementRequirements +import net.minecraft.network.chat.Component +import net.minecraft.network.protocol.game.ClientboundUpdateAdvancementsPacket +import net.minecraft.resources.ResourceLocation +import java.util.* + + +@NmsUseWithCaution +class V1_21_11SurfPaperNmsPlayerToastPacketsImpl : SurfPaperNmsPlayerToastPackets { + override fun showToast(toast: Toast) = V1_21_11PacketOperationImpl.complex { _, packets -> + val id = ResourceLocation.fromNamespaceAndPath("surfapi", "toast_${UUID.randomUUID()}") + + packets.add(showPacket(id, toast)) + packets.add(hidePacket(id)) + + packets + } + + private fun showPacket(id: ResourceLocation, toast: Toast) = + ClientboundUpdateAdvancementsPacket( + false, listOf(createAdvancement(id, toast)), emptySet(), mapOf( + id to AdvancementProgress().apply { + update(requirements) + grantProgress(CRITERION_ID) + }), true + ) + + private fun hidePacket(id: ResourceLocation) = ClientboundUpdateAdvancementsPacket( + false, emptyList(), setOf(id), emptyMap(), false + ) + + private fun createAdvancement(id: ResourceLocation, toast: Toast) = + Advancement.Builder.recipeAdvancement() + .display( + toast.icon.toNms().item, + toast.title.toNms(), + Component.empty(), + null, + toast.frame.toNms(), + true, + false, + false + ) + .requirements(requirements) + .build(id) + + companion object { + private const val CRITERION_ID = "surfapi_toast" + private val requirements by lazy { AdvancementRequirements.allOf(listOf(CRITERION_ID)) } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/extensions/AdventureNBT.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/extensions/AdventureNBT.kt new file mode 100644 index 000000000..9e1c5a98f --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/extensions/AdventureNBT.kt @@ -0,0 +1,96 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.extensions + +import net.kyori.adventure.nbt.* +import net.minecraft.nbt.* + +object AdventureNBT { + fun toNms( + adventure: CompoundBinaryTag, + accounter: NbtAccounter = NbtAccounter.unlimitedHeap() + ): CompoundTag { + return CompoundTag().also { tag -> + for ((key, value) in adventure) { + tag.put(key, toNms(value, accounter)) + } + } + } + + fun toNms( + adventure: BinaryTag, + accounter: NbtAccounter = NbtAccounter.unlimitedHeap() + ): Tag { + accounter.pushDepth() + + val nmsTag = when (adventure) { + is IntBinaryTag -> IntTag.valueOf(adventure.value()) + is ByteBinaryTag -> ByteTag.valueOf(adventure.value()) + is FloatBinaryTag -> FloatTag.valueOf(adventure.value()) + is LongBinaryTag -> LongTag.valueOf(adventure.value()) + is DoubleBinaryTag -> DoubleTag.valueOf(adventure.value()) + is ShortBinaryTag -> ShortTag.valueOf(adventure.value()) + is StringBinaryTag -> StringTag.valueOf(adventure.value()) + is ByteArrayBinaryTag -> ByteArrayTag(adventure.value()) + is IntArrayBinaryTag -> IntArrayTag(adventure.value()) + is LongArrayBinaryTag -> LongArrayTag(adventure.value()) + is EndBinaryTag -> EndTag.INSTANCE + is ListBinaryTag -> if (adventure.isEmpty) { + ListTag() + } else { + val list = ListTag() + for (entry in adventure) { + val nms = toNms(entry) + list.add(nms) + } + list + } + + is CompoundBinaryTag -> { + val tag = CompoundTag() + for ((key, entry) in adventure) { + val nms = toNms(entry) + tag.put(key, nms) + } + tag + } + + else -> throw IllegalArgumentException("Unsupported tag type: ${adventure::class}") + } + + accounter.popDepth() + + return nmsTag + } + + fun fromNms(nms: CompoundTag): CompoundBinaryTag = CompoundBinaryTag.builder().also { builder -> + nms.forEach { key, tag -> builder.put(key, fromNms(tag)) } + }.build() + + fun fromNms(nms: Tag): BinaryTag = when (nms) { + is IntTag -> IntBinaryTag.intBinaryTag(nms.intValue()) + is ByteTag -> ByteBinaryTag.byteBinaryTag(nms.byteValue()) + is FloatTag -> FloatBinaryTag.floatBinaryTag(nms.floatValue()) + is LongTag -> LongBinaryTag.longBinaryTag(nms.longValue()) + is DoubleTag -> DoubleBinaryTag.doubleBinaryTag(nms.doubleValue()) + is ShortTag -> ShortBinaryTag.shortBinaryTag(nms.shortValue()) + is StringTag -> StringBinaryTag.stringBinaryTag(nms.value()) + is ByteArrayTag -> ByteArrayBinaryTag.byteArrayBinaryTag(*nms.asByteArray) + is IntArrayTag -> IntArrayBinaryTag.intArrayBinaryTag(*nms.asIntArray) + is LongArrayTag -> LongArrayBinaryTag.longArrayBinaryTag(*nms.asLongArray) + is EndTag -> EndBinaryTag.endBinaryTag() + is ListTag -> { + val tag = ListBinaryTag.heterogeneousListBinaryTag() + for (t in nms) { + tag.add(fromNms(t)) + } + tag.build() + } + + is CompoundTag -> { + val adventure = CompoundBinaryTag.builder() + nms.forEach { key, tag -> + adventure.put(key, fromNms(tag)) + } + adventure.build() + } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/extensions/nms-extensions.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/extensions/nms-extensions.kt new file mode 100644 index 000000000..a99af87ee --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/extensions/nms-extensions.kt @@ -0,0 +1,150 @@ +@file:Suppress("UnstableApiUsage") + +package dev.slne.surf.api.paper.server.nms.v1_21_11.extensions + +import dev.slne.surf.api.paper.extensions.server +import dev.slne.surf.api.paper.nms.bridges.packets.entity.SignBlockUpdateSettings +import io.papermc.paper.advancement.AdvancementDisplay +import io.papermc.paper.advancement.AdvancementDisplay.Frame.* +import io.papermc.paper.adventure.PaperAdventure +import io.papermc.paper.math.BlockPosition +import io.papermc.paper.math.FinePosition +import io.papermc.paper.math.Position +import net.minecraft.advancements.AdvancementType +import net.minecraft.core.BlockPos +import net.minecraft.core.Holder +import net.minecraft.network.chat.Component +import net.minecraft.server.level.ServerLevel +import net.minecraft.server.level.ServerPlayer +import net.minecraft.world.entity.Display +import net.minecraft.world.inventory.MenuType +import net.minecraft.world.item.DyeColor +import net.minecraft.world.item.Item +import net.minecraft.world.item.ItemDisplayContext +import net.minecraft.world.level.block.Block +import net.minecraft.world.level.block.entity.SignText +import net.minecraft.world.phys.Vec3 +import org.bukkit.Material +import org.bukkit.Server +import org.bukkit.World +import org.bukkit.block.BlockState +import org.bukkit.block.data.BlockData +import org.bukkit.craftbukkit.CraftServer +import org.bukkit.craftbukkit.CraftWorld +import org.bukkit.craftbukkit.block.CraftBlockState +import org.bukkit.craftbukkit.block.data.CraftBlockData +import org.bukkit.craftbukkit.damage.CraftDamageSource +import org.bukkit.craftbukkit.entity.CraftEntity +import org.bukkit.craftbukkit.entity.CraftEntityType +import org.bukkit.craftbukkit.entity.CraftLivingEntity +import org.bukkit.craftbukkit.entity.CraftPlayer +import org.bukkit.craftbukkit.inventory.CraftItemStack +import org.bukkit.craftbukkit.inventory.CraftItemType +import org.bukkit.craftbukkit.util.Commodore +import org.bukkit.craftbukkit.util.CraftMagicNumbers +import org.bukkit.damage.DamageSource +import org.bukkit.entity.Display.Billboard +import org.bukkit.entity.Entity +import org.bukkit.entity.EntityType +import org.bukkit.entity.ItemDisplay.ItemDisplayTransform +import org.bukkit.entity.LivingEntity +import org.bukkit.entity.Player +import org.bukkit.event.inventory.InventoryType +import org.bukkit.inventory.ItemStack +import org.bukkit.inventory.ItemType +import org.spongepowered.math.imaginary.Quaternionf +import org.spongepowered.math.vector.Vector3f +import net.kyori.adventure.text.Component as AdventureComponent +import net.minecraft.world.item.ItemStack as NmsItemStack +import net.minecraft.world.level.block.state.BlockState as NmsBlockState +import org.joml.Quaternionf as NmsQuaternionf +import org.joml.Vector3f as NmsVector3f + +fun Player.toNms(): ServerPlayer = (this as CraftPlayer).handle +fun Material.toNmsBlock(): Block = CraftMagicNumbers.getBlock(this) +fun Material.toNmsItem(): Item = CraftMagicNumbers.getItem(this) +fun BlockData.toNms(): NmsBlockState = (this as CraftBlockData).state +fun Vector3f?.toNms(): NmsVector3f? = + if (this == null) null else NmsVector3f(this.x(), this.y(), this.z()) + +fun FinePosition.toNms() = Vec3(x(), y(), z()) +fun BlockState.toNms(): NmsBlockState = (this as CraftBlockState).handle +fun Quaternionf?.toNms(): NmsQuaternionf? = + if (this == null) null else NmsQuaternionf(x(), y(), z(), w()) + +fun Billboard.toNms(): Display.BillboardConstraints = + Display.BillboardConstraints.valueOf(this.name) + +fun ItemStack.toNms(): NmsItemStack = CraftItemStack.asNMSCopy(this) +fun ItemDisplayTransform.toNms(): ItemDisplayContext = ItemDisplayContext.BY_ID.apply(this.ordinal) +fun NmsItemStack.toBukkit(): ItemStack = CraftItemStack.asBukkitCopy(this) +val ItemType.nms: Item get() = CraftItemType.bukkitToMinecraftNew(this) +fun BlockPosition.toNms(): BlockPos = BlockPos(blockX(), blockY(), blockZ()) +fun SignBlockUpdateSettings.SignText.toNms(): SignText { + val lines = arrayOf( + line1.toNms(), + line2.toNms(), + line3.toNms(), + line4.toNms() + ) + + return SignText(lines, lines, DyeColor.BLACK, false) +} + +fun InventoryType.toNms(): MenuType<*> = when (this) { + InventoryType.ANVIL -> MenuType.ANVIL + InventoryType.BEACON -> MenuType.BEACON + InventoryType.BLAST_FURNACE -> MenuType.BLAST_FURNACE + InventoryType.BREWING -> MenuType.BREWING_STAND + InventoryType.CARTOGRAPHY -> MenuType.CARTOGRAPHY_TABLE + InventoryType.CHEST -> MenuType.GENERIC_9x6 + InventoryType.DISPENSER, InventoryType.DROPPER -> MenuType.GENERIC_3x3 + InventoryType.ENCHANTING -> MenuType.ENCHANTMENT + InventoryType.FURNACE -> MenuType.FURNACE + InventoryType.GRINDSTONE -> MenuType.GRINDSTONE + InventoryType.HOPPER -> MenuType.HOPPER + InventoryType.LECTERN -> MenuType.LECTERN + InventoryType.LOOM -> MenuType.LOOM + InventoryType.MERCHANT -> MenuType.MERCHANT + InventoryType.SHULKER_BOX -> MenuType.SHULKER_BOX + InventoryType.SMOKER -> MenuType.SMOKER + InventoryType.SMITHING -> MenuType.SMITHING + InventoryType.STONECUTTER -> MenuType.STONECUTTER + InventoryType.PLAYER -> MenuType.GENERIC_9x4 + InventoryType.CRAFTER -> MenuType.CRAFTER_3x3 + InventoryType.WORKBENCH -> MenuType.CRAFTING + InventoryType.BARREL, InventoryType.CHISELED_BOOKSHELF, InventoryType.DECORATED_POT, InventoryType.JUKEBOX, InventoryType.COMPOSTER, InventoryType.ENDER_CHEST -> MenuType.GENERIC_9x3 + InventoryType.CREATIVE, InventoryType.CRAFTING -> throw UnsupportedOperationException("Can't open a $this inventory!") + else -> throw UnsupportedOperationException("Unknown inventory type: $this") +} + +fun BlockPos.toBukkit(): BlockPosition = Position.block(x, y, z) + +fun Array.toBukkit() = this.map { it.toBukkit() } +fun AdventureComponent.toNms(): Component = PaperAdventure.asVanilla(this) +fun Component.toBukkit(): AdventureComponent = PaperAdventure.asAdventure(this) + +fun Server.toCraft() = this as CraftServer +val craftServer: CraftServer get() = server.toCraft() +val commodore: Commodore get() = CraftMagicNumbers.INSTANCE.commodore + +fun EntityType.toNms(): net.minecraft.world.entity.EntityType<*> = + CraftEntityType.bukkitToMinecraft(this) + +@Suppress("DEPRECATION") +fun EntityType.toNmsHolder() = + CraftEntityType.bukkitToMinecraftHolder(this) as Holder.Reference> + +fun World.toNms(): ServerLevel = (this as CraftWorld).handle +fun Entity.toNms(): net.minecraft.world.entity.Entity = (this as CraftEntity).handleRaw +fun LivingEntity.toNms(): net.minecraft.world.entity.LivingEntity = + (this as CraftLivingEntity).handle + +fun DamageSource.toNms(): net.minecraft.world.damagesource.DamageSource = + (this as CraftDamageSource).handle + +fun AdvancementDisplay.Frame.toNms() = when (this) { + CHALLENGE -> AdvancementType.CHALLENGE + GOAL -> AdvancementType.GOAL + TASK -> AdvancementType.TASK +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11GlowingLifecycleHandler.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11GlowingLifecycleHandler.kt new file mode 100644 index 000000000..29a5b9456 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11GlowingLifecycleHandler.kt @@ -0,0 +1,33 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.glow + +import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation +import dev.slne.surf.api.paper.nms.common.GlowingLifecycleHandler +import dev.slne.surf.api.paper.util.chunkX +import dev.slne.surf.api.paper.util.chunkZ +import org.bukkit.World +import org.bukkit.entity.Player + +class V1_21_11GlowingLifecycleHandler : GlowingLifecycleHandler { + override fun removeAllGlowingOnQuit(player: Player) { + V1_21_11SurfGlowingApiImpl.removeAllGlowingOnQuit(player) + } + + override fun getBlockGlowSpawnOperationForChunk( + player: Player, + chunkX: Int, + chunkZ: Int, + world: World + ): PacketOperation? { + val playerData = V1_21_11SurfGlowingApiImpl.getBlockPlayerData(player) ?: return null + val blockDataList = playerData.blocks + if (blockDataList.isEmpty()) return null + + val spawnOperation = PacketOperation.start() + for ((loc, block) in blockDataList) { + if (loc.chunkX != chunkX || loc.chunkZ != chunkZ || loc.world != world) continue + spawnOperation.add(block.spawn()) + } + + return spawnOperation + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11SurfGlowingApiImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11SurfGlowingApiImpl.kt new file mode 100644 index 000000000..f3064a2d4 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11SurfGlowingApiImpl.kt @@ -0,0 +1,172 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.glow + +import com.github.shynixn.mccoroutine.folia.entityDispatcher +import com.github.shynixn.mccoroutine.folia.launch +import dev.slne.surf.api.paper.extensions.server +import dev.slne.surf.api.paper.glow.SurfGlowingApi +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation +import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.V1_21_11SurfPaperNmsGlowingBridgeImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.block.V1_21_11BlockGlowingData +import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.block.BlockPlayerData +import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.entity.EntityGlowingData +import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.entity.EntityPlayerData +import dev.slne.surf.api.paper.server.nms.v1_21_11.reflection.V1_21_11Reflection +import dev.slne.surf.api.paper.util.isChunkVisible +import io.papermc.paper.adventure.PaperAdventure +import net.kyori.adventure.text.format.NamedTextColor +import org.bukkit.Location +import org.bukkit.block.Block +import org.bukkit.entity.Entity +import org.bukkit.entity.Player +import org.bukkit.plugin.java.JavaPlugin +import java.util.* +import java.util.concurrent.ConcurrentHashMap + +@NmsUseWithCaution +class V1_21_11SurfGlowingApiImpl(private val plugin: JavaPlugin) : SurfGlowingApi { + + override fun makeGlowing( + target: Entity, + viewer: Player, + color: NamedTextColor?, + ) { + makeGlowing( + target.entityId, + teamIdFor(target), + viewer, + color, + V1_21_11SurfPaperNmsGlowingBridgeImpl.INSTANCE.getCurrentFlags(target) + ) + } + + override fun makeGlowing( + targetId: Int, + teamId: String, + viewer: Player, + color: NamedTextColor?, + otherFlags: Byte, + ) { + val nmsColor = color?.let { PaperAdventure.asVanilla(it) } + val uuid = viewer.uniqueId + val playerData = entityPlayerData.computeIfAbsent(uuid) { EntityPlayerData(uuid) } + val glowingData = playerData.entities.get(targetId) + val operation = PacketOperation.start() + + if (glowingData == null) { + val newData = EntityGlowingData( + playerData, + targetId, + teamId, + nmsColor, + otherFlags + ) + playerData.entities.put(targetId, newData) + + operation.add(newData.sendGlowingFlag(enabled = true, ignorePacket = true)) + if (nmsColor != null) { + operation.add(newData.sendTeamColor()) + } + operation.execute(viewer) + return + } + + if (nmsColor == glowingData.color) return + if (nmsColor == null) { + operation.add(glowingData.removeFromTeam()) + glowingData.color = null + } else { + glowingData.color = nmsColor + operation.add(glowingData.sendTeamColor()) + } + + operation.execute(viewer) + } + + override fun makeGlowing(block: Block, viewer: Player, color: NamedTextColor) { + makeGlowing(block.location, viewer, color) + } + + override fun makeGlowing(location: Location, viewer: Player, color: NamedTextColor) { + location.checkFinite() + val blockLocation = location.toBlockLocation() + val uuid = viewer.uniqueId + val playerData = blockPlayerData.getOrPut(uuid) { BlockPlayerData(uuid) } + val blockData = playerData.blocks[blockLocation] + + if (blockData == null) { + val newData = V1_21_11BlockGlowingData(playerData, blockLocation, color) + playerData.blocks[blockLocation] = newData + + plugin.launch(plugin.entityDispatcher(viewer)) { + if (viewer.isChunkVisible(blockLocation)) { + newData.spawn().execute(viewer) + } + } + } else { + blockData.color = color + blockData.updateColor() + } + } + + override fun removeGlowing(target: Entity, viewer: Player) { + removeGlowing(target.entityId, viewer) + } + + fun removeGlowing(targetId: Int, viewer: UUID) { + val player = server.getPlayer(viewer) + + if (player == null) { + entityPlayerData[viewer]?.entities?.remove(targetId) + } else { + removeGlowing(targetId, player) + } + } + + override fun removeGlowing(targetId: Int, viewer: Player) { + val playerData = entityPlayerData[viewer.uniqueId] ?: return + val glowingData = playerData.entities.remove(targetId) ?: return + val operation = glowingData.sendGlowingFlag(enabled = false) + glowingData.removeFromTeam() + operation.execute(viewer) + } + + override fun removeGlowing(block: Block, viewer: Player) { + removeGlowing(block.location, viewer) + } + + override fun removeGlowing(location: Location, viewer: Player) { + location.checkFinite() + val blockLocation = location.toBlockLocation() + val playerData = blockPlayerData[viewer.uniqueId] ?: return + val blockData = playerData.blocks.remove(blockLocation) ?: return + + blockData.remove() + if (playerData.blocks.isEmpty()) { + blockPlayerData.remove(viewer.uniqueId) + } + } + + private fun teamIdFor(entity: Entity) = (entity as? Player)?.name ?: entity.uniqueId.toString() + + companion object { + val INSTANCE get() = SurfGlowingApi.INSTANCE as V1_21_11SurfGlowingApiImpl + + private val entityPlayerData = ConcurrentHashMap() + private val blockPlayerData = ConcurrentHashMap() + + val glowingFlag = 1 shl V1_21_11Reflection.ENTITY_PROXY.getFlagGlowing() + + fun getEntityPlayerData(player: Player): EntityPlayerData? = + entityPlayerData[player.uniqueId] + + fun getBlockPlayerData(player: Player): BlockPlayerData? = + blockPlayerData[player.uniqueId] + + fun removeAllGlowingOnQuit(player: Player) { + val uuid = player.uniqueId + V1_21_11TeamData.removeFromAll(uuid) + entityPlayerData.remove(uuid)?.entities?.clear() + blockPlayerData.remove(uuid)?.blocks?.clear() + } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11TeamData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11TeamData.kt new file mode 100644 index 000000000..264a9ab71 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11TeamData.kt @@ -0,0 +1,40 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.glow + +import net.minecraft.ChatFormatting +import net.minecraft.world.scores.PlayerTeam +import net.minecraft.world.scores.Scoreboard +import net.minecraft.world.scores.Team +import java.util.* +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.atomic.AtomicInteger + +class V1_21_11TeamData(color: ChatFormatting) { + private val scoreboard = Scoreboard() + val teamId = "glow-${uid()}${color.char}" + val team = PlayerTeam(scoreboard, teamId).apply { + collisionRule = Team.CollisionRule.NEVER + this.color = color + } + + private val seenBy = ConcurrentHashMap.newKeySet() + + fun markSeen(uniqueId: UUID) = seenBy.add(uniqueId) + fun isSeen(uniqueId: UUID): Boolean = seenBy.contains(uniqueId) + fun removeSeen(uniqueId: UUID) = seenBy.remove(uniqueId) + + companion object { + private val lastUid = AtomicInteger() + fun uid(): Int = lastUid.getAndIncrement() + + private val teams = EnumMap(ChatFormatting::class.java) + + fun getByColor(color: ChatFormatting): V1_21_11TeamData = + teams.computeIfAbsent(color) { V1_21_11TeamData(color) } + + fun getByColorOrNull(color: ChatFormatting): V1_21_11TeamData? = teams[color] + + fun removeFromAll(uuid: UUID) { + teams.values.forEach { it.removeSeen(uuid) } + } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/block/BlockPlayerData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/block/BlockPlayerData.kt new file mode 100644 index 000000000..be3f577be --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/block/BlockPlayerData.kt @@ -0,0 +1,11 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.glow.block + +import dev.slne.surf.api.core.util.mutableObject2ObjectMapOf +import dev.slne.surf.api.paper.extensions.server +import org.bukkit.Location +import java.util.* + +class BlockPlayerData(val uuid: UUID) { + val blocks = mutableObject2ObjectMapOf() + val player get() = server.getPlayer(uuid) +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/block/V1_21_11BlockGlowingData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/block/V1_21_11BlockGlowingData.kt new file mode 100644 index 000000000..60625ee89 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/block/V1_21_11BlockGlowingData.kt @@ -0,0 +1,80 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.glow.block + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsCommonBridge +import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation +import dev.slne.surf.api.paper.nms.bridges.packets.entity.SurfPaperNmsSpawnPackets +import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.V1_21_11SurfPaperNmsGlowingBridgeImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.V1_21_11PacketOperationImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.V1_21_11SurfGlowingApiImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.reflection.V1_21_11Reflection +import glm_.shl +import net.kyori.adventure.text.format.NamedTextColor +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket +import net.minecraft.world.entity.EntityType +import net.minecraft.world.phys.Vec3 +import org.bukkit.Location +import java.util.* + +@OptIn(NmsUseWithCaution::class) +class V1_21_11BlockGlowingData( + val playerData: BlockPlayerData, + val location: Location, + var color: NamedTextColor, +) { + + private val entityId: Int by lazy { SurfPaperNmsCommonBridge.nextEntityId() } + private val uuid: UUID by lazy { UUID.randomUUID() } + private var initialized = false + + fun spawn(): PacketOperation { + initialize() + + val spawnOperation = V1_21_11PacketOperationImpl.simple { + ClientboundAddEntityPacket( + entityId, + uuid, + location.x, + location.y, + location.z, + location.pitch, + location.yaw, + EntityType.SHULKER, + 0, + Vec3.ZERO, + 0.0 + ) + } + val invisibleOperation = V1_21_11SurfPaperNmsGlowingBridgeImpl.INSTANCE + .setEntityFlags(entityId, invisibleFlag) + + return spawnOperation + invisibleOperation + } + + + fun updateColor() { + val player = playerData.player ?: return + V1_21_11SurfGlowingApiImpl.INSTANCE.makeGlowing( + entityId, + uuid.toString(), + player, + color, + invisibleFlag + ) + } + + fun remove() { + playerData.player?.let { SurfPaperNmsSpawnPackets.despawn(entityId).execute(it) } + V1_21_11SurfGlowingApiImpl.INSTANCE.removeGlowing(entityId, playerData.uuid) + } + + private fun initialize() { + if (initialized) return + initialized = true + updateColor() + } + + companion object { + val invisibleFlag = 1.toByte() shl V1_21_11Reflection.ENTITY_PROXY.getFlagInvisible() + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/entity/EntityGlowingData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/entity/EntityGlowingData.kt new file mode 100644 index 000000000..3dcf23f3d --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/entity/EntityGlowingData.kt @@ -0,0 +1,73 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.glow.entity + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation +import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.V1_21_11SurfPaperNmsGlowingBridgeImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.V1_21_11PacketOperationImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.V1_21_11SurfGlowingApiImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.V1_21_11TeamData +import glm_.and +import glm_.or +import net.minecraft.ChatFormatting + +data class EntityGlowingData( + val playerData: EntityPlayerData, + val entityId: Int, + val teamId: String, + var color: ChatFormatting?, + var otherFlags: Byte, +) { + + @OptIn(NmsUseWithCaution::class) + fun sendTeamColor(): PacketOperation { + val color = color ?: return V1_21_11PacketOperationImpl.empty() + val teamData = V1_21_11TeamData.getByColor(color) + + val operation = PacketOperation.start() + if (teamData.markSeen(playerData.uuid)) { + operation.add(V1_21_11SurfPaperNmsGlowingBridgeImpl.INSTANCE.createTeam(teamData)) + } + operation.add(V1_21_11SurfPaperNmsGlowingBridgeImpl.INSTANCE.addEntityToTeam(teamData, teamId)) + + return operation + } + + @OptIn(NmsUseWithCaution::class) + fun removeFromTeam(): PacketOperation { + val color = color ?: return V1_21_11PacketOperationImpl.empty() + val teamData = V1_21_11TeamData.getByColorOrNull(color) ?: return V1_21_11PacketOperationImpl.empty() + + val operation = PacketOperation.start() + if (teamData.removeSeen(playerData.uuid)) { + operation.add( + V1_21_11SurfPaperNmsGlowingBridgeImpl.INSTANCE.removeEntityFromTeam( + teamData, + teamId + ) + ) + } + + return operation + } + + @OptIn(NmsUseWithCaution::class) + fun sendGlowingFlag(enabled: Boolean, ignorePacket: Boolean = false): PacketOperation { + val newFlags = if (enabled) { + otherFlags or V1_21_11SurfGlowingApiImpl.glowingFlag + } else { + otherFlags and V1_21_11SurfGlowingApiImpl.glowingFlag.inv() + } + + return V1_21_11SurfPaperNmsGlowingBridgeImpl.INSTANCE.setEntityFlags( + entityId, + newFlags, + ignorePacket + ) + } + + fun computeFlags(): Byte { + return (otherFlags and V1_21_11SurfGlowingApiImpl.glowingFlag.inv()).or( + if (color != null) V1_21_11SurfGlowingApiImpl.glowingFlag else 0 + ) + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/entity/EntityPlayerData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/entity/EntityPlayerData.kt new file mode 100644 index 000000000..acefb4310 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/entity/EntityPlayerData.kt @@ -0,0 +1,8 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.glow.entity + +import java.util.* +import java.util.concurrent.ConcurrentHashMap + +data class EntityPlayerData(val uuid: UUID) { + val entities = ConcurrentHashMap() +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/V1_21_11NmsPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/V1_21_11NmsPacketImpl.kt new file mode 100644 index 000000000..9f7c1a80a --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/V1_21_11NmsPacketImpl.kt @@ -0,0 +1,24 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.listener.packets.NmsPacket +import net.minecraft.network.PacketListener +import net.minecraft.network.protocol.Packet + +@NmsUseWithCaution +abstract class V1_21_11NmsPacketImpl, Listener : PacketListener>(var nmsPacket: Nms) : + NmsPacket { + val nmsClass = nmsPacket.javaClass + + override val packetClass = + javaClass.interfaces.find { NmsPacket::class.java.isAssignableFrom(it) } + ?: error("No packet interface found for ${javaClass.name}") + + companion object { + @JvmStatic + fun getFromApi(nmsPacket: NmsPacket): V1_21_11NmsPacketImpl<*, *> { + require(nmsPacket is V1_21_11NmsPacketImpl<*, *>) { "Invalid NmsPacket implementation: " + nmsPacket.javaClass.getName() } + return nmsPacket + } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/V1_21_11PacketRegistry.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/V1_21_11PacketRegistry.kt new file mode 100644 index 000000000..01f7b751a --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/V1_21_11PacketRegistry.kt @@ -0,0 +1,78 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets + +import dev.slne.surf.api.core.util.mutableObject2ObjectMapOf +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.listener.packets.clientbound.NmsClientboundPacket +import dev.slne.surf.api.paper.nms.listener.packets.serverbound.NmsServerboundPacket +import dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.clientbound.V1_21_11ClientboundDisconnectPacketImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.clientbound.V1_21_11ClientboundSystemChatPacketImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.serverbound.V1_21_11CommandSuggestionPacketImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.serverbound.V1_21_11RenameItemPacketImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.serverbound.V1_21_11ServerboundCustomPayloadPacketImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.serverbound.V1_21_11SignUpdatePacketImpl +import net.minecraft.network.protocol.Packet +import net.minecraft.network.protocol.common.ClientCommonPacketListener +import net.minecraft.network.protocol.common.ClientboundDisconnectPacket +import net.minecraft.network.protocol.common.ServerCommonPacketListener +import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket +import net.minecraft.network.protocol.game.ClientboundSystemChatPacket +import net.minecraft.network.protocol.game.ServerboundCommandSuggestionPacket +import net.minecraft.network.protocol.game.ServerboundRenameItemPacket +import net.minecraft.network.protocol.game.ServerboundSignUpdatePacket +import kotlin.reflect.KClass + +@OptIn(NmsUseWithCaution::class) +object V1_21_11PacketRegistry { + private val SERVERBOUND_PACKETS = + mutableObject2ObjectMapOf>, ServerboundPacketFactory<*, *>>() + private val CLIENTBOUND_PACKETS = + mutableObject2ObjectMapOf>, ClientboundPacketFactory<*, *>>() + + init { + // @formatter:off + // Serverbound packets + registerServerboundPacket(ServerboundSignUpdatePacket::class) { V1_21_11SignUpdatePacketImpl(it) } + registerServerboundPacket(ServerboundRenameItemPacket::class) { V1_21_11RenameItemPacketImpl(it) } + registerServerboundPacket(ServerboundCommandSuggestionPacket::class) { V1_21_11CommandSuggestionPacketImpl(it) } + registerServerboundPacket(ServerboundCustomPayloadPacket::class) { V1_21_11ServerboundCustomPayloadPacketImpl(it) } + + // Clientbound packets + registerClientboundPacket(ClientboundDisconnectPacket::class) { V1_21_11ClientboundDisconnectPacketImpl(it) } + registerClientboundPacket(ClientboundSystemChatPacket::class) { V1_21_11ClientboundSystemChatPacketImpl(it) } + // @formatter:on + } + + private fun , Api : NmsServerboundPacket> registerServerboundPacket( + nms: KClass, + factory: ServerboundPacketFactory, + ) { + SERVERBOUND_PACKETS[nms.java] = factory + } + + @Suppress("UNCHECKED_CAST") + fun > createServerboundPacketOrNull(packet: Nms): NmsServerboundPacket? { + val factory = SERVERBOUND_PACKETS[packet.javaClass] as? ServerboundPacketFactory + return factory?.create(packet) + } + + private fun , Api : NmsClientboundPacket, Listener : ClientCommonPacketListener> registerClientboundPacket( + nms: KClass, + factory: ClientboundPacketFactory, + ) { + CLIENTBOUND_PACKETS[nms.java] = factory + } + + @Suppress("UNCHECKED_CAST") + fun > createClientboundPacketOrNull(packet: Nms): NmsClientboundPacket? { + val factory = CLIENTBOUND_PACKETS[packet.javaClass] as? ClientboundPacketFactory + return factory?.create(packet) + } + + private fun interface ServerboundPacketFactory, Api : NmsServerboundPacket> { + fun create(packet: Nms): Api + } + + private fun interface ClientboundPacketFactory, Api : NmsClientboundPacket> { + fun create(packet: Nms): Api + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/clientbound/V1_21_11ClientboundDisconnectPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/clientbound/V1_21_11ClientboundDisconnectPacketImpl.kt new file mode 100644 index 000000000..afbd59908 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/clientbound/V1_21_11ClientboundDisconnectPacketImpl.kt @@ -0,0 +1,14 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.clientbound + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.listener.packets.clientbound.DisconnectPacket +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toBukkit +import net.minecraft.network.protocol.common.ClientCommonPacketListener +import net.minecraft.network.protocol.common.ClientboundDisconnectPacket + +@NmsUseWithCaution +class V1_21_11ClientboundDisconnectPacketImpl(nmsPacket: ClientboundDisconnectPacket) : + V1_21_11NmsClientboundPacketImpl(nmsPacket), + DisconnectPacket { + override val reason get() = nmsPacket.reason.toBukkit() +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/clientbound/V1_21_11ClientboundSystemChatPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/clientbound/V1_21_11ClientboundSystemChatPacketImpl.kt new file mode 100644 index 000000000..991bd4cc8 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/clientbound/V1_21_11ClientboundSystemChatPacketImpl.kt @@ -0,0 +1,25 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.clientbound + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.listener.packets.clientbound.SystemChatPacket +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toBukkit +import net.kyori.adventure.text.Component +import net.minecraft.network.protocol.game.ClientGamePacketListener +import net.minecraft.network.protocol.game.ClientboundSystemChatPacket + +@NmsUseWithCaution +class V1_21_11ClientboundSystemChatPacketImpl(nmsPacket: ClientboundSystemChatPacket) : + V1_21_11NmsClientboundPacketImpl(nmsPacket), + SystemChatPacket { + override var content: Component + get() = nmsPacket.content().toBukkit() + set(value) { + nmsPacket = ClientboundSystemChatPacket(value, nmsPacket.overlay) + } + + override var overlay: Boolean + get() = nmsPacket.overlay() + set(value) { + nmsPacket = ClientboundSystemChatPacket(nmsPacket.content(), value) + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/clientbound/V1_21_11NmsClientboundPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/clientbound/V1_21_11NmsClientboundPacketImpl.kt new file mode 100644 index 000000000..19e50bbed --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/clientbound/V1_21_11NmsClientboundPacketImpl.kt @@ -0,0 +1,12 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.clientbound + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.listener.packets.clientbound.NmsClientboundPacket +import dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.V1_21_11NmsPacketImpl +import net.minecraft.network.protocol.Packet +import net.minecraft.network.protocol.common.ClientCommonPacketListener + +@NmsUseWithCaution +abstract class V1_21_11NmsClientboundPacketImpl, Listener : ClientCommonPacketListener>( + nmsPacket: Nms, +) : NmsClientboundPacket, V1_21_11NmsPacketImpl(nmsPacket) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/serverbound/V1_21_11CommandSuggestionPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/serverbound/V1_21_11CommandSuggestionPacketImpl.kt new file mode 100644 index 000000000..8112169d8 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/serverbound/V1_21_11CommandSuggestionPacketImpl.kt @@ -0,0 +1,13 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.serverbound + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.listener.packets.serverbound.CommandSuggestionPacket +import net.minecraft.network.protocol.game.ServerboundCommandSuggestionPacket + +@NmsUseWithCaution +class V1_21_11CommandSuggestionPacketImpl(nmsPacket: ServerboundCommandSuggestionPacket) : + V1_21_11NmsServerboundPacketImpl(nmsPacket), + CommandSuggestionPacket { + override val completionId get() = nmsPacket.id + override val command get() = nmsPacket.command +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/serverbound/V1_21_11NmsServerboundPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/serverbound/V1_21_11NmsServerboundPacketImpl.kt new file mode 100644 index 000000000..814e98b5c --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/serverbound/V1_21_11NmsServerboundPacketImpl.kt @@ -0,0 +1,10 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.serverbound + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.V1_21_11NmsPacketImpl +import net.minecraft.network.protocol.Packet +import net.minecraft.network.protocol.common.ServerCommonPacketListener + +@NmsUseWithCaution +abstract class V1_21_11NmsServerboundPacketImpl>(nmsPacket: Nms) : + V1_21_11NmsPacketImpl(nmsPacket) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/serverbound/V1_21_11RenameItemPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/serverbound/V1_21_11RenameItemPacketImpl.kt new file mode 100644 index 000000000..c7b34968d --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/serverbound/V1_21_11RenameItemPacketImpl.kt @@ -0,0 +1,11 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.serverbound + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.listener.packets.serverbound.RenameItemPacket +import net.minecraft.network.protocol.game.ServerboundRenameItemPacket + +@NmsUseWithCaution +class V1_21_11RenameItemPacketImpl(nmsPacket: ServerboundRenameItemPacket) : + V1_21_11NmsServerboundPacketImpl(nmsPacket), RenameItemPacket { + override val newName: String get() = nmsPacket.name +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/serverbound/V1_21_11ServerboundCustomPayloadPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/serverbound/V1_21_11ServerboundCustomPayloadPacketImpl.kt new file mode 100644 index 000000000..75924cad6 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/serverbound/V1_21_11ServerboundCustomPayloadPacketImpl.kt @@ -0,0 +1,42 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.serverbound + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import io.papermc.paper.adventure.PaperAdventure +import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket +import net.minecraft.network.protocol.common.custom.BrandPayload +import net.minecraft.network.protocol.common.custom.CustomPacketPayload +import net.minecraft.network.protocol.common.custom.DiscardedPayload +import dev.slne.surf.api.paper.nms.listener.packets.serverbound.ServerboundCustomPayloadPacket.Payload as ApiPayload + +@NmsUseWithCaution +class V1_21_11ServerboundCustomPayloadPacketImpl( + nmsPacket: ServerboundCustomPayloadPacket +) : V1_21_11NmsServerboundPacketImpl(nmsPacket), + dev.slne.surf.api.paper.nms.listener.packets.serverbound.ServerboundCustomPayloadPacket { + + override var payload: ApiPayload + get() = toApiPayload(nmsPacket.payload); + set(value) { + nmsPacket = ServerboundCustomPayloadPacket(toNmsPayload(value)) + } + + companion object { + private fun toApiPayload(nmsPayload: CustomPacketPayload): ApiPayload = when (nmsPayload) { + is BrandPayload -> ApiPayload.Brand(nmsPayload.brand) + is DiscardedPayload -> ApiPayload.Discarded( + id = PaperAdventure.asAdventure(nmsPayload.id), + data = nmsPayload.data + ) + + else -> error("Unknown CustomPacketPayload type: ${nmsPayload.type()}") + } + + private fun toNmsPayload(apiPayload: ApiPayload): CustomPacketPayload = when (apiPayload) { + is ApiPayload.Brand -> BrandPayload(apiPayload.brand) + is ApiPayload.Discarded -> DiscardedPayload( + PaperAdventure.asVanilla(apiPayload.id), + apiPayload.data + ) + } + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/serverbound/V1_21_11SignUpdatePacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/serverbound/V1_21_11SignUpdatePacketImpl.kt new file mode 100644 index 000000000..83540ba5b --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/serverbound/V1_21_11SignUpdatePacketImpl.kt @@ -0,0 +1,19 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.serverbound + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.listener.packets.serverbound.SignUpdatePacket +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toBukkit +import net.minecraft.network.protocol.game.ServerboundSignUpdatePacket + +@NmsUseWithCaution +class V1_21_11SignUpdatePacketImpl(nmsPacket: ServerboundSignUpdatePacket) : + V1_21_11NmsServerboundPacketImpl(nmsPacket), SignUpdatePacket { + override val position get() = nmsPacket.pos.toBukkit() + override val lines: Array get() = nmsPacket.lines + override val isFrontText get() = nmsPacket.isFrontText + + override fun getLine(line: Int): String { + require(line in 1..4) { "Line must be between 1 and 4" } + return lines[line - 1] + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/listener/V1_21_11GlowingPacketListener.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/listener/V1_21_11GlowingPacketListener.kt new file mode 100644 index 000000000..b6d459a5d --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/listener/V1_21_11GlowingPacketListener.kt @@ -0,0 +1,100 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.packet.listener + +import com.github.benmanes.caffeine.cache.Caffeine +import com.sksamuel.aedile.core.expireAfterWrite +import dev.slne.surf.api.core.util.mutableObjectListOf +import dev.slne.surf.api.core.util.toMutableObjectList +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.packet.listener.listener.PacketListener +import dev.slne.surf.api.paper.packet.listener.listener.annotation.ClientboundListener +import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.V1_21_11SurfGlowingApiImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.reflection.V1_21_11Reflection +import glm_.or +import net.minecraft.network.protocol.Packet +import net.minecraft.network.protocol.game.ClientboundBundlePacket +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket +import net.minecraft.network.syncher.SynchedEntityData.DataValue +import org.bukkit.entity.Player +import kotlin.time.Duration.Companion.seconds + +@OptIn(NmsUseWithCaution::class) +object V1_21_11GlowingPacketListener : PacketListener { + + val ignoreCache = Caffeine.newBuilder() + .weakKeys() + .expireAfterWrite(5.seconds) + .build, Unit>() + + fun ignorePacket(packet: Packet<*>) { + ignoreCache.put(packet, Unit) + } + + @ClientboundListener + fun onBundlePacket(packet: ClientboundBundlePacket, player: Player): ClientboundBundlePacket { + val bundles = packet.subPackets().toMutableObjectList() + bundles.replaceAll { subPacket -> + if (subPacket is ClientboundSetEntityDataPacket) { + updatePacketIfNeeded(subPacket, player) + } else { + subPacket + } + } + + return ClientboundBundlePacket(bundles) + } + + @ClientboundListener + fun onSetEntityDataPacket( + packet: ClientboundSetEntityDataPacket, + player: Player, + ): ClientboundSetEntityDataPacket { + return updatePacketIfNeeded(packet, player) + } + + private fun updatePacketIfNeeded( + packet: ClientboundSetEntityDataPacket, + player: Player + ): ClientboundSetEntityDataPacket { + // Ignore packets that we don't care about + if (ignoreCache.asMap().remove(packet) != null) { + return packet + } + + val playerData = V1_21_11SurfGlowingApiImpl.getEntityPlayerData(player) ?: return packet + val glowingData = playerData.entities.get(packet.id) ?: return packet + val incoming = packet.packedItems + var flagsFound = false + var edited = false + val newItems = mutableObjectListOf>(incoming.size + 1) + val dataFlagsShared = V1_21_11Reflection.ENTITY_PROXY.getDataFlagsSharedId() + val dataFlagsSharedId = dataFlagsShared.id + + for (dataValue in incoming) { + if (dataValue.id == dataFlagsSharedId) { + flagsFound = true + val current = dataValue.value as Byte + glowingData.otherFlags = current + val withGlow: Byte = current or V1_21_11SurfGlowingApiImpl.glowingFlag + + if (withGlow != current) { + edited = true + newItems.add(DataValue(dataFlagsSharedId, dataFlagsShared.serializer, withGlow)) + } else { + newItems.add(dataValue) + } + } else { + newItems.add(dataValue) + } + } + + if (!edited && !flagsFound) { + val withGlow = glowingData.otherFlags or V1_21_11SurfGlowingApiImpl.glowingFlag + if (withGlow != 0.toByte()) { + edited = true + newItems.add(DataValue(dataFlagsSharedId, dataFlagsShared.serializer, withGlow)) + } + } + + return if (edited) ClientboundSetEntityDataPacket(packet.id, newItems) else packet + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/lore/V1_21_11PacketLoreListener.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/lore/V1_21_11PacketLoreListener.kt new file mode 100644 index 000000000..ca63a657e --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/lore/V1_21_11PacketLoreListener.kt @@ -0,0 +1,388 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.packet.lore + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.packet.listener.listener.PacketListener +import dev.slne.surf.api.paper.packet.listener.listener.annotation.ClientboundListener +import dev.slne.surf.api.paper.packet.listener.listener.annotation.ServerboundListener +import dev.slne.surf.api.paper.packet.lore.SurfPaperPacketLoreHandler +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toBukkit +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNms +import dev.slne.surf.api.paper.util.namespacedKey +import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap +import it.unimi.dsi.fastutil.objects.ObjectArrayList +import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet +import it.unimi.dsi.fastutil.objects.ObjectLists +import net.kyori.adventure.text.format.TextDecoration +import net.minecraft.core.component.DataComponents +import net.minecraft.network.protocol.game.* +import net.minecraft.server.level.ServerPlayer +import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.component.CustomData +import net.minecraft.world.item.component.ItemLore +import org.bukkit.NamespacedKey +import org.bukkit.plugin.Plugin +import net.minecraft.network.chat.Component as MinecraftComponent + +/** + * PacketLoreListener is a class that implements PacketListenerAbstract and is responsible for + * handling the modification of lore on item stacks in packet events. + */ +@OptIn(NmsUseWithCaution::class) +object V1_21_11PacketLoreListener : PacketListener { + private val globalHandlersByPlugin = + Object2ObjectLinkedOpenHashMap>() + + private val keyedHandlersByPlugin = + Object2ObjectLinkedOpenHashMap>() + + @Volatile + private var keyedHandlersSnapshot: Map = emptyMap() + + @Volatile + private var globalHandlersSnapshot: Array = emptyArray() + + private val ORIGINAL_LORE_KEY = namespacedKey("original_lore") + private val ORIGINAL_LORE_KEY_STRING = ORIGINAL_LORE_KEY.asString() + + private fun hasAnyHandlers(): Boolean = + keyedHandlersSnapshot.isNotEmpty() || globalHandlersSnapshot.isNotEmpty() + + @ServerboundListener + fun onPacketReceive(event: ServerboundSetCreativeModeSlotPacket) { + makeCleanItemStack(event.itemStack()) + } + + @ClientboundListener + fun onWindowItem(event: ClientboundContainerSetContentPacket): ClientboundContainerSetContentPacket { + if (!hasAnyHandlers()) return event + + val sourceItems = event.items + val updatedItems = ObjectArrayList(sourceItems.size) + + var changed = false + + for (i in sourceItems.indices) { + val original = sourceItems[i] + val updated = makeUpdatedItemStack(original) + + if (updated !== original) { + changed = true + } + + updatedItems.add(updated) + } + + val originalCarried = event.carriedItem() + val updatedCarried = makeUpdatedItemStack(originalCarried) + + if (updatedCarried !== originalCarried) { + changed = true + } + + if (!changed) { + return event + } + + return ClientboundContainerSetContentPacket( + event.containerId(), + event.stateId(), + updatedItems, + updatedCarried + ) + } + + @ClientboundListener + fun onSetSlotPacket(event: ClientboundContainerSetSlotPacket): ClientboundContainerSetSlotPacket { + val original = event.item + val updated = makeUpdatedItemStack(original) + + if (updated === original) { + return event + } + + return ClientboundContainerSetSlotPacket( + event.containerId, + event.stateId, + event.slot, + updated + ) + } + + @ClientboundListener + fun onSetPlayerInventoryPacket(event: ClientboundSetPlayerInventoryPacket): ClientboundSetPlayerInventoryPacket { + val original = event.contents + val updated = makeUpdatedItemStack(original) + + if (updated === original) { + return event + } + + return ClientboundSetPlayerInventoryPacket( + event.slot(), + updated + ) + } + + @ServerboundListener + fun onContainerClickPacket( + event: ServerboundContainerClickPacket, + player: ServerPlayer + ): ServerboundContainerClickPacket { + if (!hasAnyHandlers()) return event + + val container = player.containerMenu + val currentStateId = container.stateId + + val brokenStateId = if (event.stateId() == currentStateId) { + currentStateId - 1 + } else { + event.stateId() + } + + if (brokenStateId == event.stateId()) return event + + return ServerboundContainerClickPacket( + event.containerId(), + brokenStateId, + event.slotNum(), + event.buttonNum(), + event.containerInput(), + event.changedSlots(), + event.carriedItem() + ) + } + + @ClientboundListener + fun onSetCursorItemPacket(event: ClientboundSetCursorItemPacket): ClientboundSetCursorItemPacket { + val original = event.contents + val updated = makeUpdatedItemStack(original) + + if (updated === original) { + return event + } + + return ClientboundSetCursorItemPacket(updated) + } + + /** + * Returns the original item if: + * - item is empty + * - no handlers exist + * - no keyed handler matches and no global handler exists + * - handlers run but lore result is identical + * + * Only copies the stack if at least one handler will actually run. + */ + private fun makeUpdatedItemStack( + original: ItemStack, + ): ItemStack { + if (original.isEmpty) return original + + // One volatile read + val keyedSnapshot = keyedHandlersSnapshot + val globalSnapshot = globalHandlersSnapshot + + if (keyedSnapshot.isEmpty() && globalSnapshot.isEmpty()) { + return original + } + + /* + * We need Bukkit PDC for the current handler API, but only when there + * are keyed handlers to consider. The original mirror is used to cheaply + * determine whether any keyed handlers actually match. + */ + val matchingKeyedHandlers = if (keyedSnapshot.isNotEmpty()) { + val originalBukkitStack = original.asBukkitMirror() + val originalPdc = originalBukkitStack.persistentDataContainer + resolveMatchingKeyedHandlers( + originalPdc.keys, + keyedSnapshot + ) + } else { + ObjectLists.emptyList() + } + + if (matchingKeyedHandlers.isEmpty() && globalSnapshot.isEmpty()) { + return original + } + + /* + * From here on, we know that at least one handler will run. + * Only now create a copy. + */ + val item = original.copy() + val bukkitStack = item.asBukkitMirror() + val pdc = bukkitStack.persistentDataContainer + + val originalLore = item.getOrDefault(DataComponents.LORE, ItemLore.EMPTY) + val originalLines = originalLore.lines + + val mutableLore = originalLines.mapTo( + ObjectArrayList(originalLines.size) + ) { it.toBukkit() } + + for (i in matchingKeyedHandlers.indices) { + matchingKeyedHandlers[i].handleLore(mutableLore, pdc, bukkitStack) + } + + for (i in globalSnapshot.indices) { + globalSnapshot[i].handleLore(mutableLore, pdc, bukkitStack) + } + + val updatedLines = ObjectArrayList(mutableLore.size) + for (i in mutableLore.indices) { + val line = + mutableLore[i].decorationIfAbsent(TextDecoration.ITALIC, TextDecoration.State.FALSE) + updatedLines.add(line.toNms()) + } + + val updatedLore = ItemLore(updatedLines) + + if (updatedLore == originalLore) { + return original + } + + item.set(DataComponents.LORE, updatedLore) + CustomData.update(DataComponents.CUSTOM_DATA, item) { tag -> + if (!tag.contains(ORIGINAL_LORE_KEY_STRING)) { + tag.store(ORIGINAL_LORE_KEY_STRING, ItemLore.CODEC, originalLore) + } + } + + return item + } + + private fun makeCleanItemStack( + stack: ItemStack, + ): ItemStack { + if (stack.isEmpty) { + return stack + } + + val customData = stack.get(DataComponents.CUSTOM_DATA) ?: return stack + if (!customData.contains(ORIGINAL_LORE_KEY_STRING)) { + return stack + } + + CustomData.update(DataComponents.CUSTOM_DATA, stack) { tag -> + val originalLore = tag.read(ORIGINAL_LORE_KEY_STRING, ItemLore.CODEC) + originalLore.ifPresent { lore -> + stack.set(DataComponents.LORE, lore) + tag.remove(ORIGINAL_LORE_KEY_STRING) + } + } + + return stack + } + + private fun resolveMatchingKeyedHandlers( + itemKeys: Set, + keyedSnapshot: Map, + ): List { + if (itemKeys.isEmpty() || keyedSnapshot.isEmpty()) { + return emptyList() + } + + var result: ObjectArrayList? = null + for (key in itemKeys) { + val handler = keyedSnapshot[key] ?: continue + + if (result == null) { + result = ObjectArrayList(2) + } + + result.add(handler) + } + + return result ?: emptyList() + } + + fun register(plugin: Plugin, identifier: NamespacedKey, listener: SurfPaperPacketLoreHandler) { + synchronized(this) { + check(!keyedHandlersSnapshot.containsKey(identifier)) { + "A PacketLore handler for $identifier is already registered!" + } + + val handlers = + keyedHandlersByPlugin.computeIfAbsent(plugin) { Object2ObjectLinkedOpenHashMap() } + + val previous = handlers.putIfAbsent(identifier, listener) + check(previous == null) { + "A PacketLore handler for $identifier is already registered for plugin ${plugin.name}!" + } + + val newSnapshot = Object2ObjectLinkedOpenHashMap(keyedHandlersSnapshot) + newSnapshot[identifier] = listener + keyedHandlersSnapshot = newSnapshot + } + } + + fun register(plugin: Plugin, listener: SurfPaperPacketLoreHandler) { + synchronized(this) { + val handlers = + globalHandlersByPlugin.computeIfAbsent(plugin) { ObjectLinkedOpenHashSet() } + if (handlers.add(listener)) { + rebuildGlobalHandlersSnapshot() + } else { + error("A PacketLore handler identical to the provided one (${listener.javaClass.name}) is already registered for plugin ${plugin.name}!") + } + } + } + + fun unregister(identifier: NamespacedKey) { + synchronized(this) { + if (!keyedHandlersSnapshot.containsKey(identifier)) { + return + } + + var emptyPlugin: Plugin? = null + + for ((plugin, handlers) in keyedHandlersByPlugin) { + if (handlers.remove(identifier) != null) { + if (handlers.isEmpty()) { + emptyPlugin = plugin + } + break + } + } + + if (emptyPlugin != null) { + keyedHandlersByPlugin.remove(emptyPlugin) + } + + val newSnapshot = Object2ObjectLinkedOpenHashMap(keyedHandlersSnapshot) + newSnapshot.remove(identifier) + keyedHandlersSnapshot = newSnapshot + } + } + + fun unregister(plugin: Plugin) { + synchronized(this) { + val removedGlobal = globalHandlersByPlugin.remove(plugin) != null + if (removedGlobal) { + rebuildGlobalHandlersSnapshot() + } + + val removedKeyed = keyedHandlersByPlugin.remove(plugin) + if (removedKeyed != null) { + val newSnapshot = Object2ObjectLinkedOpenHashMap(keyedHandlersSnapshot) + for (identifier in removedKeyed.keys) { + newSnapshot.remove(identifier) + } + keyedHandlersSnapshot = newSnapshot + } + } + } + + private fun rebuildGlobalHandlersSnapshot() { + val snapshot = ObjectArrayList() + + globalHandlersByPlugin.object2ObjectEntrySet().fastForEach { (plugin, handlers) -> + if (plugin.isEnabled) { + snapshot.addAll(handlers) + } + } + + globalHandlersSnapshot = snapshot.toTypedArray() + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/lore/V1_21_11PacketLoreRegistry.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/lore/V1_21_11PacketLoreRegistry.kt new file mode 100644 index 000000000..bbe912d8f --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/lore/V1_21_11PacketLoreRegistry.kt @@ -0,0 +1,24 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.packet.lore + +import dev.slne.surf.api.paper.nms.common.PacketLoreRegistry +import dev.slne.surf.api.paper.packet.lore.SurfPaperPacketLoreHandler +import org.bukkit.NamespacedKey +import org.bukkit.plugin.Plugin + +class V1_21_11PacketLoreRegistry : PacketLoreRegistry { + override fun register(plugin: Plugin, identifier: NamespacedKey, listener: SurfPaperPacketLoreHandler) { + V1_21_11PacketLoreListener.register(plugin, identifier, listener) + } + + override fun register(plugin: Plugin, listener: SurfPaperPacketLoreHandler) { + V1_21_11PacketLoreListener.register(plugin, listener) + } + + override fun unregister(identifier: NamespacedKey) { + V1_21_11PacketLoreListener.unregister(identifier) + } + + override fun unregister(plugin: Plugin) { + V1_21_11PacketLoreListener.unregister(plugin) + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11EntityProxy.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11EntityProxy.kt new file mode 100644 index 000000000..79e25a57d --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11EntityProxy.kt @@ -0,0 +1,23 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.reflection + +import net.minecraft.network.syncher.EntityDataAccessor +import net.minecraft.world.entity.Entity +import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldGetter +import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies +import xyz.jpenilla.reflectionremapper.proxy.annotation.Static + +@Proxies(Entity::class) +interface V1_21_11EntityProxy { + + @FieldGetter("FLAG_GLOWING") + @Static + fun getFlagGlowing(): Int + + @FieldGetter("FLAG_INVISIBLE") + @Static + fun getFlagInvisible(): Int + + @FieldGetter("DATA_SHARED_FLAGS_ID") + @Static + fun getDataFlagsSharedId(): EntityDataAccessor +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11Reflection.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11Reflection.kt new file mode 100644 index 000000000..44cc4bfd8 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11Reflection.kt @@ -0,0 +1,37 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.reflection + +import dev.slne.surf.api.core.reflection.SurfReflection +import dev.slne.surf.api.core.reflection.createProxy +import dev.slne.surf.api.paper.util.reflectionProxy +import xyz.jpenilla.reflectionremapper.ReflectionRemapper +import xyz.jpenilla.reflectionremapper.proxy.ReflectionProxyFactory + +object V1_21_11Reflection { + lateinit var SERVER_STATS_COUNTER_PROXY: V1_21_11ServerStatsCounterProxy + private set + lateinit var ENTITY_PROXY: V1_21_11EntityProxy + private set + lateinit var SERVER_CONNECTION_LISTENER_PROXY: V1_21_11ServerConnectionListenerProxy + private set + lateinit var VANILLA_ARGUMENT_PROVIDER_IMPL_PROXY: V1_21_11VanillaArgumentProviderImplProxy + private set + lateinit var VANILLA_ARGUMENT_PROVIDER_PROXY: V1_21_11VanillaArgumentProviderProxy + private set + + fun initialize() { + val remapper = ReflectionRemapper.forReobfMappingsInPaperJar() + val proxyFactory = + ReflectionProxyFactory.create(remapper, V1_21_11Reflection::class.java.classLoader) + + SERVER_STATS_COUNTER_PROXY = proxyFactory.reflectionProxy() + ENTITY_PROXY = proxyFactory.reflectionProxy() + SERVER_CONNECTION_LISTENER_PROXY = + proxyFactory.reflectionProxy() + VANILLA_ARGUMENT_PROVIDER_IMPL_PROXY = + SurfReflection.createProxy() + VANILLA_ARGUMENT_PROVIDER_PROXY = SurfReflection.createProxy() + + // gc the remapper + System.gc() + } +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11ServerConnectionListenerProxy.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11ServerConnectionListenerProxy.kt new file mode 100644 index 000000000..a8e0a39c9 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11ServerConnectionListenerProxy.kt @@ -0,0 +1,12 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.reflection + +import io.netty.channel.ChannelFuture +import net.minecraft.server.network.ServerConnectionListener +import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldGetter +import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies + +@Proxies(ServerConnectionListener::class) +interface V1_21_11ServerConnectionListenerProxy { + @FieldGetter("channels") + fun getChannels(instance: ServerConnectionListener): List +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11ServerStatsCounterProxy.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11ServerStatsCounterProxy.kt new file mode 100644 index 000000000..a6c9dfc54 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11ServerStatsCounterProxy.kt @@ -0,0 +1,20 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.reflection + +import com.google.gson.Gson +import com.google.gson.JsonElement +import net.minecraft.stats.ServerStatsCounter +import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldGetter +import xyz.jpenilla.reflectionremapper.proxy.annotation.MethodName +import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies +import xyz.jpenilla.reflectionremapper.proxy.annotation.Static + +@Proxies(ServerStatsCounter::class) +interface V1_21_11ServerStatsCounterProxy { + + @MethodName("toJson") + fun toJson(statsCounter: ServerStatsCounter): JsonElement + + @FieldGetter("GSON") + @Static + fun getGson(): Gson +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11VanillaArgumentProviderImplProxy.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11VanillaArgumentProviderImplProxy.kt new file mode 100644 index 000000000..5e9fb9d2d --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11VanillaArgumentProviderImplProxy.kt @@ -0,0 +1,15 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.reflection + +import com.mojang.brigadier.arguments.ArgumentType +import com.mojang.brigadier.exceptions.CommandSyntaxException +import dev.slne.surf.api.core.reflection.Name +import dev.slne.surf.api.core.reflection.SurfProxy +import io.papermc.paper.command.brigadier.argument.VanillaArgumentProviderImpl + +@SurfProxy(VanillaArgumentProviderImpl::class) +interface V1_21_11VanillaArgumentProviderImplProxy { + + @Name("wrap") + @Throws(CommandSyntaxException::class) + fun wrap(instance: Any, base: Any, converter: Any): ArgumentType<*> +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11VanillaArgumentProviderProxy.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11VanillaArgumentProviderProxy.kt new file mode 100644 index 000000000..67082b302 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11VanillaArgumentProviderProxy.kt @@ -0,0 +1,14 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.reflection + +import dev.slne.surf.api.core.reflection.Name +import dev.slne.surf.api.core.reflection.Static +import dev.slne.surf.api.core.reflection.SurfProxy + + +@SurfProxy(qualifiedName = "io.papermc.paper.command.brigadier.argument.VanillaArgumentProvider") +interface V1_21_11VanillaArgumentProviderProxy { + + @Static + @Name("provider") + fun provider(): Any +} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/region/V1_21_11TickThreadGuard.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/region/V1_21_11TickThreadGuard.kt new file mode 100644 index 000000000..588c2b71f --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/region/V1_21_11TickThreadGuard.kt @@ -0,0 +1,65 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.region + +import ca.spottedleaf.moonrise.common.util.TickThread +import dev.slne.surf.api.paper.region.TickThreadGuard +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNms +import dev.slne.surf.api.paper.util.chunkX +import dev.slne.surf.api.paper.util.chunkZ +import io.papermc.paper.math.Position +import net.minecraft.core.BlockPos +import net.minecraft.world.phys.AABB +import org.bukkit.World +import org.bukkit.entity.Entity +import org.bukkit.util.BoundingBox + +@Suppress("UnstableApiUsage") +class V1_21_11TickThreadGuard : TickThreadGuard { + + override fun ensureTickThread(world: World, pos: Position, reason: String) { + TickThread.ensureTickThread(world.toNms(), pos.chunkX, pos.chunkZ, reason) + } + + override fun ensureTickThread( + world: World, + pos: Position, + blockRadius: Int, + reason: String + ) { + TickThread.ensureTickThread( + world.toNms(), + BlockPos(pos.blockX(), pos.blockY(), pos.blockZ()), + blockRadius, + reason + ) + } + + override fun ensureTickThread( + world: World, + chunkX: Int, + chunkZ: Int, + reason: String + ) { + TickThread.ensureTickThread(world.toNms(), chunkX, chunkZ, reason) + } + + override fun ensureTickThread(entity: Entity, reason: String) { + TickThread.ensureTickThread(entity.toNms(), reason) + } + + override fun ensureTickThread(world: World, box: BoundingBox, reason: String) { + TickThread.ensureTickThread( + world.toNms(), + AABB(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ), + reason + ) + } + + override fun ensureTickThread( + world: World, + blockX: Double, + blockZ: Double, + reason: String + ) { + TickThread.ensureTickThread(world.toNms(), blockX, blockZ, reason) + } +} diff --git a/surf-api-paper/surf-api-paper-server/build.gradle.kts b/surf-api-paper/surf-api-paper-server/build.gradle.kts index cc8d49581..2586aba15 100644 --- a/surf-api-paper/surf-api-paper-server/build.gradle.kts +++ b/surf-api-paper/surf-api-paper-server/build.gradle.kts @@ -24,6 +24,7 @@ dependencies { // Version-specific NMS modules (runtime only - loaded via ServiceLoader) runtimeOnly(projects.surfApiPaper.surfApiPaperNms.surfApiPaperNmsV261) + runtimeOnly(projects.surfApiPaper.surfApiPaperNms.surfApiPaperNmsV12111) compileOnly(libs.placeholder.api) From 420c9ad853d60e886cfdb0947e0f3ef776151e99 Mon Sep 17 00:00:00 2001 From: TheBjoRedCraft Date: Tue, 14 Apr 2026 08:51:25 +0200 Subject: [PATCH 07/34] feat: add multiversion support for NMS 1.21.11 and 26.1, update dependencies and versioning --- build.gradle.kts | 2 +- gradle.properties | 2 +- .../slne/surf/api/paper/nms/common/NmsProvider.kt | 6 ++---- .../dev/slne/surf/api/paper/nms/common/NmsVersion.kt | 7 ++----- .../surf-api-paper-nms-v1-21-11/build.gradle.kts | 2 +- .../bridges/V1_21_11SurfPaperNmsItemBridgeImpl.kt | 5 +++-- .../bridges/V1_21_11SurfPaperNmsNbtBridgeImpl.kt | 4 ++-- .../V1_21_11SurfPaperNmsPlayerToastPacketsImpl.kt | 10 +++++----- .../packet/lore/V1_21_11PacketLoreListener.kt | 2 +- .../nms/v1_21_11/reflection/V1_21_11ItemProxy.kt | 12 ++++++++++++ .../nms/v1_21_11/reflection/V1_21_11Reflection.kt | 6 +++++- .../surf-api-paper-nms-v26-1/build.gradle.kts | 2 +- .../dev/slne/surf/api/paper/server/PaperInstance.kt | 8 ++++++++ 13 files changed, 44 insertions(+), 24 deletions(-) create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11ItemProxy.kt diff --git a/build.gradle.kts b/build.gradle.kts index 89bed798a..0f648f8a0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,7 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinJvmExtension plugins { - id("io.papermc.paperweight.userdev") version "2.0.0-beta.20" apply false + id("io.papermc.paperweight.userdev") version "2.0.0-beta.21" apply false } allprojects { diff --git a/gradle.properties b/gradle.properties index f30e17d9a..06832df4e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,6 +7,6 @@ org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled javaVersion=25 mcVersion=26.1.1 group=dev.slne.surf.api -version=3.0.10 +version=3.1.0 relocationPrefix=dev.slne.surf.api.libs snapshot=false diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt index 285af491f..10669fa3e 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt @@ -102,10 +102,8 @@ interface NmsProvider { ) providers.firstOrNull { it.version == version } - ?: throw IllegalStateException( - "No NMS provider found for version $version. " + - "Available providers: ${providers.map { it.version }.joinToString()}" - ) + ?: providers.maxByOrNull { it.version.versionPrefix } + ?: error("No NmsProvider implementations found") } } } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersion.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersion.kt index b70f33ed1..ccbc6a613 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersion.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersion.kt @@ -16,15 +16,12 @@ enum class NmsVersion(val versionPrefix: String) { * The NMS version of the currently running Minecraft server. * * Detected at runtime from `Bukkit.getMinecraftVersion()`. - * - * @throws IllegalStateException if the server version is not supported + * Uses latest provided NMS version if no exact match is found. */ val current: NmsVersion by lazy { val mcVersion = Bukkit.getMinecraftVersion() entries.firstOrNull { mcVersion.startsWith(it.versionPrefix) } - ?: throw IllegalStateException( - "Unsupported Minecraft version: $mcVersion. Supported versions: ${entries.joinToString { "${it.name} (${it.versionPrefix}*)" }}" - ) + ?: entries.maxByOrNull { it.versionPrefix } ?: error("No NMS versions defined!") } } } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/build.gradle.kts b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/build.gradle.kts index dc7ec4de8..c39dd476b 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/build.gradle.kts +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/build.gradle.kts @@ -13,7 +13,7 @@ dependencies { api(projects.surfApiPaper.surfApiPaperNms.surfApiPaperNmsCommon) api(projects.surfApiCore.surfApiCoreServer) - paperweight.paperDevBundle(libs.canvas.api.get().version) + paperweight.paperDevBundle("1.21.11-R0.1-SNAPSHOT") compileOnly(libs.placeholder.api) compileOnly(libs.reflection.remapper) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsItemBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsItemBridgeImpl.kt index e1bdfc4e9..2050fecc2 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsItemBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsItemBridgeImpl.kt @@ -3,13 +3,13 @@ package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsItemBridge import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.nms +import dev.slne.surf.api.paper.server.nms.v1_21_11.reflection.V1_21_11Reflection import net.minecraft.core.component.DataComponentMap import net.minecraft.core.component.DataComponents import org.bukkit.inventory.ItemType @NmsUseWithCaution class V1_21_11SurfPaperNmsItemBridgeImpl : SurfPaperNmsItemBridge { - override fun setDefaultMaxStackSize(item: ItemType, maxStackSize: Int) { require(maxStackSize in 1..100) { "Max stack size must be between 1 and 100" } @@ -19,6 +19,7 @@ class V1_21_11SurfPaperNmsItemBridgeImpl : SurfPaperNmsItemBridge { .set(DataComponents.MAX_STACK_SIZE, maxStackSize) .build() - nmsItem.builtInRegistryHolder().bindComponents(updatedComponents) + + V1_21_11Reflection.ITEM_PROXY.setComponents(nmsItem, updatedComponents) } } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsNbtBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsNbtBridgeImpl.kt index f311be643..6e81bf5ae 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsNbtBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsNbtBridgeImpl.kt @@ -9,13 +9,13 @@ import net.minecraft.core.component.DataComponentPatch import net.minecraft.core.component.DataComponents import net.minecraft.nbt.CompoundTag import net.minecraft.world.item.component.CustomData +import net.minecraft.world.item.component.TypedEntityData import org.bukkit.entity.EntityType import org.bukkit.inventory.ItemStack import kotlin.jvm.optionals.getOrNull @NmsUseWithCaution class V1_21_11SurfPaperNmsNbtBridgeImpl : SurfPaperNmsNbtBridge { - private val log = logger() override fun makeItemStackEntityInvisible( @@ -28,7 +28,7 @@ class V1_21_11SurfPaperNmsNbtBridgeImpl : SurfPaperNmsNbtBridge { nbt.putBoolean("Invisible", true) nbt.putString("id", invisibleEntityType.key.asString()) - val entityData = CustomData.of(nbt) + val entityData = TypedEntityData.decodeEntity(nbt) val patch = DataComponentPatch.builder() .set(DataComponents.ENTITY_DATA, entityData) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/player/V1_21_11SurfPaperNmsPlayerToastPacketsImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/player/V1_21_11SurfPaperNmsPlayerToastPacketsImpl.kt index 0f4f36950..c222bf7e4 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/player/V1_21_11SurfPaperNmsPlayerToastPacketsImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/packets/player/V1_21_11SurfPaperNmsPlayerToastPacketsImpl.kt @@ -10,14 +10,14 @@ import net.minecraft.advancements.AdvancementProgress import net.minecraft.advancements.AdvancementRequirements import net.minecraft.network.chat.Component import net.minecraft.network.protocol.game.ClientboundUpdateAdvancementsPacket -import net.minecraft.resources.ResourceLocation +import net.minecraft.resources.Identifier import java.util.* @NmsUseWithCaution class V1_21_11SurfPaperNmsPlayerToastPacketsImpl : SurfPaperNmsPlayerToastPackets { override fun showToast(toast: Toast) = V1_21_11PacketOperationImpl.complex { _, packets -> - val id = ResourceLocation.fromNamespaceAndPath("surfapi", "toast_${UUID.randomUUID()}") + val id = Identifier.fromNamespaceAndPath("surfapi", "toast_${UUID.randomUUID()}") packets.add(showPacket(id, toast)) packets.add(hidePacket(id)) @@ -25,7 +25,7 @@ class V1_21_11SurfPaperNmsPlayerToastPacketsImpl : SurfPaperNmsPlayerToastPacket packets } - private fun showPacket(id: ResourceLocation, toast: Toast) = + private fun showPacket(id: Identifier, toast: Toast) = ClientboundUpdateAdvancementsPacket( false, listOf(createAdvancement(id, toast)), emptySet(), mapOf( id to AdvancementProgress().apply { @@ -34,11 +34,11 @@ class V1_21_11SurfPaperNmsPlayerToastPacketsImpl : SurfPaperNmsPlayerToastPacket }), true ) - private fun hidePacket(id: ResourceLocation) = ClientboundUpdateAdvancementsPacket( + private fun hidePacket(id: Identifier) = ClientboundUpdateAdvancementsPacket( false, emptyList(), setOf(id), emptyMap(), false ) - private fun createAdvancement(id: ResourceLocation, toast: Toast) = + private fun createAdvancement(id: Identifier, toast: Toast) = Advancement.Builder.recipeAdvancement() .display( toast.icon.toNms().item, diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/lore/V1_21_11PacketLoreListener.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/lore/V1_21_11PacketLoreListener.kt index ca63a657e..b5eed7de1 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/lore/V1_21_11PacketLoreListener.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/lore/V1_21_11PacketLoreListener.kt @@ -146,7 +146,7 @@ object V1_21_11PacketLoreListener : PacketListener { brokenStateId, event.slotNum(), event.buttonNum(), - event.containerInput(), + event.clickType(), event.changedSlots(), event.carriedItem() ) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11ItemProxy.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11ItemProxy.kt new file mode 100644 index 000000000..980f22568 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11ItemProxy.kt @@ -0,0 +1,12 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.reflection + +import dev.slne.surf.api.core.reflection.Field +import dev.slne.surf.api.core.reflection.SurfProxy +import net.minecraft.core.component.DataComponentMap +import net.minecraft.world.item.Item + +@SurfProxy(Item::class) +interface V1_21_11ItemProxy { + @Field("components", Field.Type.SETTER, overrideFinal = true) + fun setComponents(item: Item, components: DataComponentMap) +} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11Reflection.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11Reflection.kt index 44cc4bfd8..4c46e55c8 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11Reflection.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11Reflection.kt @@ -11,6 +11,8 @@ object V1_21_11Reflection { private set lateinit var ENTITY_PROXY: V1_21_11EntityProxy private set + lateinit var ITEM_PROXY: V1_21_11ItemProxy + private set lateinit var SERVER_CONNECTION_LISTENER_PROXY: V1_21_11ServerConnectionListenerProxy private set lateinit var VANILLA_ARGUMENT_PROVIDER_IMPL_PROXY: V1_21_11VanillaArgumentProviderImplProxy @@ -25,11 +27,13 @@ object V1_21_11Reflection { SERVER_STATS_COUNTER_PROXY = proxyFactory.reflectionProxy() ENTITY_PROXY = proxyFactory.reflectionProxy() + ITEM_PROXY = proxyFactory.reflectionProxy() SERVER_CONNECTION_LISTENER_PROXY = proxyFactory.reflectionProxy() VANILLA_ARGUMENT_PROVIDER_IMPL_PROXY = SurfReflection.createProxy() - VANILLA_ARGUMENT_PROVIDER_PROXY = SurfReflection.createProxy() + VANILLA_ARGUMENT_PROVIDER_PROXY = + SurfReflection.createProxy() // gc the remapper System.gc() diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/build.gradle.kts b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/build.gradle.kts index 7d1546943..97fa8fa77 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/build.gradle.kts +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/build.gradle.kts @@ -13,7 +13,7 @@ dependencies { api(projects.surfApiPaper.surfApiPaperNms.surfApiPaperNmsCommon) api(projects.surfApiCore.surfApiCoreServer) - paperweight.paperDevBundle(libs.paper.api.get().version) + paperweight.paperDevBundle("26.1+") compileOnly(libs.placeholder.api) compileOnly(libs.reflection.remapper) diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/PaperInstance.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/PaperInstance.kt index 536b0cc4e..cd22cce88 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/PaperInstance.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/PaperInstance.kt @@ -2,10 +2,12 @@ package dev.slne.surf.api.paper.server import dev.slne.surf.api.core.server.CoreInstance import dev.slne.surf.api.paper.SurfApiPaper +import dev.slne.surf.api.paper.nms.common.NmsProvider import dev.slne.surf.api.paper.server.impl.SurfApiPaperImpl import dev.slne.surf.api.paper.server.inventory.framework.InventoryLoader import dev.slne.surf.api.paper.server.listener.ListenerManager import dev.slne.surf.api.paper.server.packet.PacketApiLoader +import org.bukkit.Bukkit object PaperInstance : CoreInstance() { @@ -19,6 +21,12 @@ object PaperInstance : CoreInstance() { override suspend fun onEnable() { super.onEnable() + val pluginVersion = plugin.pluginMeta.version + val mcVersion = Bukkit.getMinecraftVersion() + val nmsVersion = NmsProvider.current.version + + plugin.logger.info("\u001B[36m\u001B[1mLoading surf-api v$pluginVersion for minecraft $mcVersion with nms $nmsVersion") + PacketApiLoader.onEnable() InventoryLoader.enable() ListenerManager.registerListeners() From 64eb38bf3cfa1846b73b0af9baaf04406d2598eb Mon Sep 17 00:00:00 2001 From: TheBjoRedCraft Date: Tue, 14 Apr 2026 08:58:58 +0200 Subject: [PATCH 08/34] feat: enhance logging for NmsProvider and NmsVersion detection --- .../surf/api/paper/nms/common/NmsProvider.kt | 23 +++++++++++++++---- .../surf/api/paper/nms/common/NmsVersion.kt | 22 ++++++++++++++---- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt index 10669fa3e..3f613183e 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt @@ -89,6 +89,8 @@ interface NmsProvider { fun shutdown() companion object { + private val log = dev.slne.surf.api.core.util.logger() + /** * Loads the [NmsProvider] for the currently running Minecraft version. * @@ -99,11 +101,22 @@ interface NmsProvider { val providers = java.util.ServiceLoader.load( NmsProvider::class.java, NmsProvider::class.java.classLoader - ) - - providers.firstOrNull { it.version == version } - ?: providers.maxByOrNull { it.version.versionPrefix } - ?: error("No NmsProvider implementations found") + ).toList() + + log.atInfo().log("Looking for NmsProvider with version: %s", version) + log.atInfo().log("Available NmsProviders: %s", providers.map { "${it.version.name} (${it.version.versionPrefix})" }.joinToString(", ")) + + val matched = providers.firstOrNull { it.version == version } + if (matched != null) { + log.atInfo().log("Found matching NmsProvider: %s", matched.version.name) + matched + } else { + log.atWarning().log("No exact match for NmsProvider version %s, using fallback", version) + val fallback = providers.maxByOrNull { it.version.versionPrefix } + ?: error("No NmsProvider implementations found") + log.atWarning().log("Selected fallback NmsProvider: %s", fallback.version.name) + fallback + } } } } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersion.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersion.kt index ccbc6a613..84e86b23f 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersion.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersion.kt @@ -1,5 +1,6 @@ package dev.slne.surf.api.paper.nms.common +import dev.slne.surf.api.core.util.logger import org.bukkit.Bukkit /** @@ -8,10 +9,12 @@ import org.bukkit.Bukkit * @property versionPrefix The version prefix used to match `Bukkit.getMinecraftVersion()`. */ enum class NmsVersion(val versionPrefix: String) { - V1_21_11("1.21"), - V26_1("26."); + V1_21_11("1.21.11"), + V26_1("26.1"); companion object { + private val log = logger() + /** * The NMS version of the currently running Minecraft server. * @@ -20,8 +23,19 @@ enum class NmsVersion(val versionPrefix: String) { */ val current: NmsVersion by lazy { val mcVersion = Bukkit.getMinecraftVersion() - entries.firstOrNull { mcVersion.startsWith(it.versionPrefix) } - ?: entries.maxByOrNull { it.versionPrefix } ?: error("No NMS versions defined!") + log.atInfo().log("Detected Minecraft version from Bukkit: '%s'", mcVersion) + log.atInfo().log("Available NMS versions: %s", entries.joinToString(", ") { "${it.name}(${it.versionPrefix})" }) + + val matched = entries.firstOrNull { mcVersion.startsWith(it.versionPrefix) } + if (matched != null) { + log.atInfo().log("Selected NMS version: %s", matched.name) + matched + } else { + log.atWarning().log("No exact NMS version match found, using fallback (maxByOrNull)") + val fallback = entries.maxByOrNull { it.versionPrefix } ?: error("No NMS versions defined!") + log.atWarning().log("Fallback NMS version selected: %s", fallback.name) + fallback + } } } } From dce266e96d8b9e09962f407260be2ddb33cfb493 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Apr 2026 07:11:09 +0000 Subject: [PATCH 09/34] fix: add manual META-INF/services files for NmsProvider ServiceLoader registration The @AutoService KSP processor may not always generate the service file correctly (e.g. due to paperweight dev bundle resolution issues). Adding manual service files ensures V1_21_11NmsProvider and V26_1NmsProvider are always discoverable by ServiceLoader at runtime. Also makes ServiceLoader iteration robust against class loading failures and updates the NMS template generator to auto-generate service files. Agent-Logs-Url: https://github.com/SLNE-Development/surf-api/sessions/1c421ac7-9194-4697-91fd-1373913d3900 Co-authored-by: TheBjoRedCraft <143264463+TheBjoRedCraft@users.noreply.github.com> --- .../surf/api/gen/nms/NmsTemplateGenerator.kt | 25 +++++++++++++++++ .../surf/api/paper/nms/common/NmsProvider.kt | 27 ++++++++++++++++--- ...slne.surf.api.paper.nms.common.NmsProvider | 1 + ...slne.surf.api.paper.nms.common.NmsProvider | 1 + 4 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider diff --git a/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsTemplateGenerator.kt b/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsTemplateGenerator.kt index 47da3ad88..c84362723 100644 --- a/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsTemplateGenerator.kt +++ b/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsTemplateGenerator.kt @@ -74,10 +74,35 @@ class NmsTemplateGenerator( generated++ } + // Generate META-INF/services file for ServiceLoader registration + generateServiceFile(repoRoot, target) + println("Generated $generated files for ${target.versionId} in ${targetSourceRoot.toAbsolutePath()}") return generated } + /** + * Generates the META-INF/services file for ServiceLoader registration. + * This ensures the NmsProvider implementation is discoverable at runtime, + * regardless of whether KSP annotation processing runs successfully. + */ + private fun generateServiceFile(repoRoot: Path, target: NmsVersionConfig) { + val serviceDir = repoRoot.resolve(target.sourceModulePath) + .resolve("src/main/resources/META-INF/services") + serviceDir.createDirectories() + + // Derive the provider class name from the reference module's NmsProvider + val referenceProviderPackage = "dev.slne.surf.api.paper.server.nms.$referenceVersionId" + val referenceProviderClass = "${referenceClassPrefix}NmsProvider" + val targetProviderPackage = "dev.slne.surf.api.paper.server.nms.${target.versionId}" + val targetProviderClass = "${target.classPrefix}NmsProvider" + + val serviceFile = serviceDir.resolve("dev.slne.surf.api.paper.nms.common.NmsProvider") + serviceFile.writeText("$targetProviderPackage.$targetProviderClass\n") + + println("Generated service file for ${target.versionId}: $targetProviderPackage.$targetProviderClass") + } + /** * Transforms a relative path from the reference module to the target module. * Replaces the reference package directory segments with target ones. diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt index 3f613183e..302e05c02 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt @@ -98,13 +98,29 @@ interface NmsProvider { */ val current: NmsProvider by lazy { val version = NmsVersion.current - val providers = java.util.ServiceLoader.load( + val serviceLoader = java.util.ServiceLoader.load( NmsProvider::class.java, NmsProvider::class.java.classLoader - ).toList() + ) + + // Iterate safely — skip providers whose classes can't be loaded + // (e.g. version-specific NMS classes not present on this server) + val providers = buildList { + val iterator = serviceLoader.iterator() + while (iterator.hasNext()) { + try { + add(iterator.next()) + } catch (e: java.util.ServiceConfigurationError) { + log.atWarning().withCause(e).log("Skipping NmsProvider that failed to load") + } + } + } log.atInfo().log("Looking for NmsProvider with version: %s", version) - log.atInfo().log("Available NmsProviders: %s", providers.map { "${it.version.name} (${it.version.versionPrefix})" }.joinToString(", ")) + log.atInfo().log( + "Available NmsProviders: %s", + providers.joinToString(", ") { "${it.version.name} (${it.version.versionPrefix})" } + ) val matched = providers.firstOrNull { it.version == version } if (matched != null) { @@ -113,7 +129,10 @@ interface NmsProvider { } else { log.atWarning().log("No exact match for NmsProvider version %s, using fallback", version) val fallback = providers.maxByOrNull { it.version.versionPrefix } - ?: error("No NmsProvider implementations found") + ?: error( + "No NmsProvider implementations found for version $version. " + + "Ensure the correct NMS module is included in the classpath." + ) log.atWarning().log("Selected fallback NmsProvider: %s", fallback.version.name) fallback } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider new file mode 100644 index 000000000..07ebd5c38 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider @@ -0,0 +1 @@ +dev.slne.surf.api.paper.server.nms.v1_21_11.V1_21_11NmsProvider diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider new file mode 100644 index 000000000..b5e249f89 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider @@ -0,0 +1 @@ +dev.slne.surf.api.paper.server.nms.v26_1.V26_1NmsProvider From efb23fdb5afe9a72a7348f0011340df37baf0dcb Mon Sep 17 00:00:00 2001 From: TheBjoRedCraft Date: Tue, 14 Apr 2026 09:14:55 +0200 Subject: [PATCH 10/34] feat: enhance logging for NmsProvider and NmsVersion detection --- .../slne/surf/api/paper/nms/common/NmsProvider.kt | 5 ++--- .../slne/surf/api/paper/nms/common/NmsVersion.kt | 13 ++++++------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt index 302e05c02..53c1221b8 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt @@ -103,8 +103,6 @@ interface NmsProvider { NmsProvider::class.java.classLoader ) - // Iterate safely — skip providers whose classes can't be loaded - // (e.g. version-specific NMS classes not present on this server) val providers = buildList { val iterator = serviceLoader.iterator() while (iterator.hasNext()) { @@ -127,7 +125,8 @@ interface NmsProvider { log.atInfo().log("Found matching NmsProvider: %s", matched.version.name) matched } else { - log.atWarning().log("No exact match for NmsProvider version %s, using fallback", version) + log.atWarning() + .log("No exact match for NmsProvider version %s, using fallback", version) val fallback = providers.maxByOrNull { it.version.versionPrefix } ?: error( "No NmsProvider implementations found for version $version. " + diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersion.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersion.kt index 84e86b23f..c2c1e5994 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersion.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersion.kt @@ -23,17 +23,16 @@ enum class NmsVersion(val versionPrefix: String) { */ val current: NmsVersion by lazy { val mcVersion = Bukkit.getMinecraftVersion() - log.atInfo().log("Detected Minecraft version from Bukkit: '%s'", mcVersion) - log.atInfo().log("Available NMS versions: %s", entries.joinToString(", ") { "${it.name}(${it.versionPrefix})" }) - val matched = entries.firstOrNull { mcVersion.startsWith(it.versionPrefix) } if (matched != null) { - log.atInfo().log("Selected NMS version: %s", matched.name) matched } else { - log.atWarning().log("No exact NMS version match found, using fallback (maxByOrNull)") - val fallback = entries.maxByOrNull { it.versionPrefix } ?: error("No NMS versions defined!") - log.atWarning().log("Fallback NMS version selected: %s", fallback.name) + val fallback = + entries.maxByOrNull { it.versionPrefix } ?: error("No NMS versions defined!") + log.atWarning().log( + "There is no matching nms version, using fallback NMS version: %s", + fallback.name + ) fallback } } From a64dde7896922478024056b314539021406717d0 Mon Sep 17 00:00:00 2001 From: TheBjoRedCraft Date: Tue, 14 Apr 2026 09:35:20 +0200 Subject: [PATCH 11/34] feat: add multiversion support for NMS 1.21.11 and 26.1, update NmsProvider and related classes --- .../surf/api/paper/nms/common/NmsProvider.kt | 24 ++------ .../nms/v1_21_11/V1_21_11NmsProvider.kt | 61 +++++++++++++------ .../v1_21_11/reflection/V1_21_11ItemProxy.kt | 8 +-- ...slne.surf.api.paper.nms.common.NmsProvider | 1 - .../server/nms/v26_1/V26_1NmsProvider.kt | 53 ++++++++++------ ...slne.surf.api.paper.nms.common.NmsProvider | 1 - .../surf-api-paper-server/build.gradle.kts | 3 +- 7 files changed, 88 insertions(+), 63 deletions(-) delete mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider delete mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt index 53c1221b8..8720b006a 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt @@ -11,6 +11,7 @@ import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerPack import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToastPackets import dev.slne.surf.api.paper.packet.listener.listener.PacketListener import dev.slne.surf.api.paper.region.TickThreadGuard +import java.util.* /** * Main interface for version-specific NMS operations. @@ -98,27 +99,15 @@ interface NmsProvider { */ val current: NmsProvider by lazy { val version = NmsVersion.current - val serviceLoader = java.util.ServiceLoader.load( + val providers = ServiceLoader.load( NmsProvider::class.java, NmsProvider::class.java.classLoader - ) - - val providers = buildList { - val iterator = serviceLoader.iterator() - while (iterator.hasNext()) { - try { - add(iterator.next()) - } catch (e: java.util.ServiceConfigurationError) { - log.atWarning().withCause(e).log("Skipping NmsProvider that failed to load") - } - } - } + ).toList() log.atInfo().log("Looking for NmsProvider with version: %s", version) log.atInfo().log( "Available NmsProviders: %s", - providers.joinToString(", ") { "${it.version.name} (${it.version.versionPrefix})" } - ) + providers.joinToString(", ") { "${it.version.name} (${it.version.versionPrefix})" }) val matched = providers.firstOrNull { it.version == version } if (matched != null) { @@ -128,10 +117,7 @@ interface NmsProvider { log.atWarning() .log("No exact match for NmsProvider version %s, using fallback", version) val fallback = providers.maxByOrNull { it.version.versionPrefix } - ?: error( - "No NmsProvider implementations found for version $version. " + - "Ensure the correct NMS module is included in the classpath." - ) + ?: error("No NmsProvider implementations found") log.atWarning().log("Selected fallback NmsProvider: %s", fallback.version.name) fallback } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt index 12f65513c..9e710f163 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt @@ -10,11 +10,7 @@ import dev.slne.surf.api.paper.nms.bridges.packets.entity.SurfPaperNmsSpawnPacke import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerChatPackets import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerPackets import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToastPackets -import dev.slne.surf.api.paper.nms.common.GlowingLifecycleHandler -import dev.slne.surf.api.paper.nms.common.NmsPacketBridgeHandler -import dev.slne.surf.api.paper.nms.common.NmsProvider -import dev.slne.surf.api.paper.nms.common.NmsVersion -import dev.slne.surf.api.paper.nms.common.PacketLoreRegistry +import dev.slne.surf.api.paper.nms.common.* import dev.slne.surf.api.paper.packet.listener.listener.PacketListener import dev.slne.surf.api.paper.region.TickThreadGuard import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.* @@ -40,24 +36,51 @@ class V1_21_11NmsProvider : NmsProvider { private var glowingApi: V1_21_11SurfGlowingApiImpl? = null override fun createNmsBridge(): SurfPaperNmsBridge = V1_21_11SurfPaperNmsBridgeImpl() - override fun createCommonBridge(): SurfPaperNmsCommonBridge = V1_21_11SurfPaperNmsCommonBridgeImpl() - override fun createEntityBridge(): SurfPaperNmsEntityBridge = V1_21_11SurfPaperNmsEntityBridgeImpl() + override fun createCommonBridge(): SurfPaperNmsCommonBridge = + V1_21_11SurfPaperNmsCommonBridgeImpl() + + override fun createEntityBridge(): SurfPaperNmsEntityBridge = + V1_21_11SurfPaperNmsEntityBridgeImpl() + override fun createItemBridge(): SurfPaperNmsItemBridge = V1_21_11SurfPaperNmsItemBridgeImpl() override fun createNbtBridge(): SurfPaperNmsNbtBridge = V1_21_11SurfPaperNmsNbtBridgeImpl() - override fun createGlowingBridge(): SurfPaperNmsGlowingBridge = V1_21_11SurfPaperNmsGlowingBridgeImpl() - override fun createStatsBridge(): SurfPaperNmsStatsBridge = V1_21_11SurfPaperNmsStatsBridgeImpl() - override fun createLootTableBridge(): SurfPaperNmsLootTableBridge = V1_21_11SurfPaperNmsLootTableBridgeImpl() - override fun createCommandArgumentTypesBridge(): SurfPaperNmsCommandArgumentTypesBridge = V1_21_11SurfPaperNmsCommandArgumentTypesBridgeImpl() - override fun createPacketBridges(): SurfPaperNmsPacketBridges = V1_21_11SurfPaperNmsPacketBridgesImpl() - override fun createBlockPackets(): SurfPaperNmsBlockPackets = V1_21_11SurfPaperNmsBlockPacketsImpl() - override fun createSpawnPackets(): SurfPaperNmsSpawnPackets = V1_21_11SurfPaperNmsSpawnPacketsImpl() - override fun createPlayerPackets(): SurfPaperNmsPlayerPackets = V1_21_11SurfPaperNmsPlayerPacketsImpl() - override fun createPlayerChatPackets(): SurfPaperNmsPlayerChatPackets = V1_21_11SurfPaperNmsPlayerChatPacketsImpl() - override fun createPlayerToastPackets(): SurfPaperNmsPlayerToastPackets = V1_21_11SurfPaperNmsPlayerToastPacketsImpl() + override fun createGlowingBridge(): SurfPaperNmsGlowingBridge = + V1_21_11SurfPaperNmsGlowingBridgeImpl() + + override fun createStatsBridge(): SurfPaperNmsStatsBridge = + V1_21_11SurfPaperNmsStatsBridgeImpl() + + override fun createLootTableBridge(): SurfPaperNmsLootTableBridge = + V1_21_11SurfPaperNmsLootTableBridgeImpl() + + override fun createCommandArgumentTypesBridge(): SurfPaperNmsCommandArgumentTypesBridge = + V1_21_11SurfPaperNmsCommandArgumentTypesBridgeImpl() + + override fun createPacketBridges(): SurfPaperNmsPacketBridges = + V1_21_11SurfPaperNmsPacketBridgesImpl() + + override fun createBlockPackets(): SurfPaperNmsBlockPackets = + V1_21_11SurfPaperNmsBlockPacketsImpl() + + override fun createSpawnPackets(): SurfPaperNmsSpawnPackets = + V1_21_11SurfPaperNmsSpawnPacketsImpl() + + override fun createPlayerPackets(): SurfPaperNmsPlayerPackets = + V1_21_11SurfPaperNmsPlayerPacketsImpl() + + override fun createPlayerChatPackets(): SurfPaperNmsPlayerChatPackets = + V1_21_11SurfPaperNmsPlayerChatPacketsImpl() + + override fun createPlayerToastPackets(): SurfPaperNmsPlayerToastPackets = + V1_21_11SurfPaperNmsPlayerToastPacketsImpl() + override fun createTickThreadGuard(): TickThreadGuard = V1_21_11TickThreadGuard() - override fun createPacketBridgeHandler(): NmsPacketBridgeHandler = V1_21_11NmsPacketBridgeHandler() + override fun createPacketBridgeHandler(): NmsPacketBridgeHandler = + V1_21_11NmsPacketBridgeHandler() + override fun createPacketLoreRegistry(): PacketLoreRegistry = V1_21_11PacketLoreRegistry() - override fun createGlowingLifecycleHandler(): GlowingLifecycleHandler = V1_21_11GlowingLifecycleHandler() + override fun createGlowingLifecycleHandler(): GlowingLifecycleHandler = + V1_21_11GlowingLifecycleHandler() override fun createGlowingApi(): SurfGlowingApi { val plugin = JavaPlugin.getProvidingPlugin(V1_21_11NmsProvider::class.java) as JavaPlugin diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11ItemProxy.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11ItemProxy.kt index 980f22568..28a91789e 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11ItemProxy.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/reflection/V1_21_11ItemProxy.kt @@ -1,12 +1,12 @@ package dev.slne.surf.api.paper.server.nms.v1_21_11.reflection -import dev.slne.surf.api.core.reflection.Field -import dev.slne.surf.api.core.reflection.SurfProxy import net.minecraft.core.component.DataComponentMap import net.minecraft.world.item.Item +import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldSetter +import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies -@SurfProxy(Item::class) +@Proxies(Item::class) interface V1_21_11ItemProxy { - @Field("components", Field.Type.SETTER, overrideFinal = true) + @FieldSetter("components") fun setComponents(item: Item, components: DataComponentMap) } \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider deleted file mode 100644 index 07ebd5c38..000000000 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider +++ /dev/null @@ -1 +0,0 @@ -dev.slne.surf.api.paper.server.nms.v1_21_11.V1_21_11NmsProvider diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt index ba1ef7933..6b1170aec 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt @@ -10,11 +10,7 @@ import dev.slne.surf.api.paper.nms.bridges.packets.entity.SurfPaperNmsSpawnPacke import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerChatPackets import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerPackets import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToastPackets -import dev.slne.surf.api.paper.nms.common.GlowingLifecycleHandler -import dev.slne.surf.api.paper.nms.common.NmsPacketBridgeHandler -import dev.slne.surf.api.paper.nms.common.NmsProvider -import dev.slne.surf.api.paper.nms.common.NmsVersion -import dev.slne.surf.api.paper.nms.common.PacketLoreRegistry +import dev.slne.surf.api.paper.nms.common.* import dev.slne.surf.api.paper.packet.listener.listener.PacketListener import dev.slne.surf.api.paper.region.TickThreadGuard import dev.slne.surf.api.paper.server.nms.v26_1.bridges.* @@ -40,24 +36,47 @@ class V26_1NmsProvider : NmsProvider { private var glowingApi: V26_1SurfGlowingApiImpl? = null override fun createNmsBridge(): SurfPaperNmsBridge = V26_1SurfPaperNmsBridgeImpl() - override fun createCommonBridge(): SurfPaperNmsCommonBridge = V26_1SurfPaperNmsCommonBridgeImpl() - override fun createEntityBridge(): SurfPaperNmsEntityBridge = V26_1SurfPaperNmsEntityBridgeImpl() + override fun createCommonBridge(): SurfPaperNmsCommonBridge = + V26_1SurfPaperNmsCommonBridgeImpl() + + override fun createEntityBridge(): SurfPaperNmsEntityBridge = + V26_1SurfPaperNmsEntityBridgeImpl() + override fun createItemBridge(): SurfPaperNmsItemBridge = V26_1SurfPaperNmsItemBridgeImpl() override fun createNbtBridge(): SurfPaperNmsNbtBridge = V26_1SurfPaperNmsNbtBridgeImpl() - override fun createGlowingBridge(): SurfPaperNmsGlowingBridge = V26_1SurfPaperNmsGlowingBridgeImpl() + override fun createGlowingBridge(): SurfPaperNmsGlowingBridge = + V26_1SurfPaperNmsGlowingBridgeImpl() + override fun createStatsBridge(): SurfPaperNmsStatsBridge = V26_1SurfPaperNmsStatsBridgeImpl() - override fun createLootTableBridge(): SurfPaperNmsLootTableBridge = V26_1SurfPaperNmsLootTableBridgeImpl() - override fun createCommandArgumentTypesBridge(): SurfPaperNmsCommandArgumentTypesBridge = V26_1SurfPaperNmsCommandArgumentTypesBridgeImpl() - override fun createPacketBridges(): SurfPaperNmsPacketBridges = V26_1SurfPaperNmsPacketBridgesImpl() - override fun createBlockPackets(): SurfPaperNmsBlockPackets = V26_1SurfPaperNmsBlockPacketsImpl() - override fun createSpawnPackets(): SurfPaperNmsSpawnPackets = V26_1SurfPaperNmsSpawnPacketsImpl() - override fun createPlayerPackets(): SurfPaperNmsPlayerPackets = V26_1SurfPaperNmsPlayerPacketsImpl() - override fun createPlayerChatPackets(): SurfPaperNmsPlayerChatPackets = V26_1SurfPaperNmsPlayerChatPacketsImpl() - override fun createPlayerToastPackets(): SurfPaperNmsPlayerToastPackets = V26_1SurfPaperNmsPlayerToastPacketsImpl() + override fun createLootTableBridge(): SurfPaperNmsLootTableBridge = + V26_1SurfPaperNmsLootTableBridgeImpl() + + override fun createCommandArgumentTypesBridge(): SurfPaperNmsCommandArgumentTypesBridge = + V26_1SurfPaperNmsCommandArgumentTypesBridgeImpl() + + override fun createPacketBridges(): SurfPaperNmsPacketBridges = + V26_1SurfPaperNmsPacketBridgesImpl() + + override fun createBlockPackets(): SurfPaperNmsBlockPackets = + V26_1SurfPaperNmsBlockPacketsImpl() + + override fun createSpawnPackets(): SurfPaperNmsSpawnPackets = + V26_1SurfPaperNmsSpawnPacketsImpl() + + override fun createPlayerPackets(): SurfPaperNmsPlayerPackets = + V26_1SurfPaperNmsPlayerPacketsImpl() + + override fun createPlayerChatPackets(): SurfPaperNmsPlayerChatPackets = + V26_1SurfPaperNmsPlayerChatPacketsImpl() + + override fun createPlayerToastPackets(): SurfPaperNmsPlayerToastPackets = + V26_1SurfPaperNmsPlayerToastPacketsImpl() + override fun createTickThreadGuard(): TickThreadGuard = V26_1TickThreadGuard() override fun createPacketBridgeHandler(): NmsPacketBridgeHandler = V26_1NmsPacketBridgeHandler() override fun createPacketLoreRegistry(): PacketLoreRegistry = V26_1PacketLoreRegistry() - override fun createGlowingLifecycleHandler(): GlowingLifecycleHandler = V26_1GlowingLifecycleHandler() + override fun createGlowingLifecycleHandler(): GlowingLifecycleHandler = + V26_1GlowingLifecycleHandler() override fun createGlowingApi(): SurfGlowingApi { val plugin = JavaPlugin.getProvidingPlugin(V26_1NmsProvider::class.java) as JavaPlugin diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider deleted file mode 100644 index b5e249f89..000000000 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider +++ /dev/null @@ -1 +0,0 @@ -dev.slne.surf.api.paper.server.nms.v26_1.V26_1NmsProvider diff --git a/surf-api-paper/surf-api-paper-server/build.gradle.kts b/surf-api-paper/surf-api-paper-server/build.gradle.kts index 2586aba15..f00db308a 100644 --- a/surf-api-paper/surf-api-paper-server/build.gradle.kts +++ b/surf-api-paper/surf-api-paper-server/build.gradle.kts @@ -22,9 +22,8 @@ dependencies { paperweight.paperDevBundle(libs.paper.api.get().version) - // Version-specific NMS modules (runtime only - loaded via ServiceLoader) - runtimeOnly(projects.surfApiPaper.surfApiPaperNms.surfApiPaperNmsV261) runtimeOnly(projects.surfApiPaper.surfApiPaperNms.surfApiPaperNmsV12111) + runtimeOnly(projects.surfApiPaper.surfApiPaperNms.surfApiPaperNmsV261) compileOnly(libs.placeholder.api) From 7d44ce96bea69b9533f2404288abc97046d5c793 Mon Sep 17 00:00:00 2001 From: TheBjoRedCraft Date: Tue, 14 Apr 2026 10:18:43 +0200 Subject: [PATCH 12/34] feat: exclude Kotlin dependencies from shadowJar configuration --- surf-api-velocity/surf-api-velocity-server/build.gradle.kts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/surf-api-velocity/surf-api-velocity-server/build.gradle.kts b/surf-api-velocity/surf-api-velocity-server/build.gradle.kts index 4eb6adfc7..b90d74eb0 100644 --- a/surf-api-velocity/surf-api-velocity-server/build.gradle.kts +++ b/surf-api-velocity/surf-api-velocity-server/build.gradle.kts @@ -24,6 +24,10 @@ tasks { shadowJar { val relocationPrefix: String by project relocate("it.unimi.dsi.fastutil", "$relocationPrefix.fastutil") + + dependencies { + exclude(dependency("org.jetbrains.kotlin:.*")) + } } } From 995d58356b7990168eef016fb199737590e19cd8 Mon Sep 17 00:00:00 2001 From: TheBjoRedCraft Date: Tue, 14 Apr 2026 10:21:48 +0200 Subject: [PATCH 13/34] feat: remove Kotlin dependencies exclusion from shadowJar configuration --- surf-api-velocity/surf-api-velocity-server/build.gradle.kts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/surf-api-velocity/surf-api-velocity-server/build.gradle.kts b/surf-api-velocity/surf-api-velocity-server/build.gradle.kts index b90d74eb0..4eb6adfc7 100644 --- a/surf-api-velocity/surf-api-velocity-server/build.gradle.kts +++ b/surf-api-velocity/surf-api-velocity-server/build.gradle.kts @@ -24,10 +24,6 @@ tasks { shadowJar { val relocationPrefix: String by project relocate("it.unimi.dsi.fastutil", "$relocationPrefix.fastutil") - - dependencies { - exclude(dependency("org.jetbrains.kotlin:.*")) - } } } From 468467314d1c0c7375bf2f8b182a1d405867ef0c Mon Sep 17 00:00:00 2001 From: TheBjoRedCraft Date: Tue, 14 Apr 2026 10:34:17 +0200 Subject: [PATCH 14/34] fix: update NmsProvider to correctly load multiple providers from ServiceLoader --- .../kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt index 8720b006a..5f339e846 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt @@ -102,7 +102,8 @@ interface NmsProvider { val providers = ServiceLoader.load( NmsProvider::class.java, NmsProvider::class.java.classLoader - ).toList() + ) + .toList() // TODO: Bug: Finds only a single provider, even if multiple are present. The Provider which is declared as a dependency first is found. log.atInfo().log("Looking for NmsProvider with version: %s", version) log.atInfo().log( From ddd2a48e66aa36f100c9a8ea91cbbb475d8823d5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Apr 2026 18:15:40 +0000 Subject: [PATCH 15/34] fix: resolve ClassCastException in NMS INSTANCE companions and remove dead glow/packet code The version-specific INSTANCE companions were casting from the ServiceLoader-loaded proxy to the concrete impl type, causing ClassCastException. Changed to lateinit var set by NmsProvider during bridge/API creation. Also removed old NMS-dependent dead code from surf-api-paper-server that cannot work on 1.21.11 (compiled against 26.1 NMS): - SurfGlowingApiImpl, GlowingPacketListener, TeamData - BlockGlowingData, BlockPlayerData, EntityGlowingData, EntityPlayerData - SurfPaperNmsGlowingBridgeImpl, PacketLoreListener These are fully replaced by version-specific implementations in the NMS modules (V1_21_11 and V26_1). Agent-Logs-Url: https://github.com/SLNE-Development/surf-api/sessions/9e5b042e-c45e-4c65-8062-df05e010e09f Co-authored-by: TheBjoRedCraft <143264463+TheBjoRedCraft@users.noreply.github.com> --- .../nms/v1_21_11/V1_21_11NmsProvider.kt | 8 +- .../V1_21_11SurfPaperNmsGlowingBridgeImpl.kt | 3 +- .../glow/V1_21_11SurfGlowingApiImpl.kt | 3 +- .../server/nms/v26_1/V26_1NmsProvider.kt | 8 +- .../V26_1SurfPaperNmsGlowingBridgeImpl.kt | 3 +- .../nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt | 3 +- .../server/impl/glow/GlowingPacketListener.kt | 99 ----- .../server/impl/glow/SurfGlowingApiImpl.kt | 173 -------- .../api/paper/server/impl/glow/TeamData.kt | 40 -- .../impl/glow/block/BlockGlowingData.kt | 80 ---- .../server/impl/glow/block/BlockPlayerData.kt | 11 - .../impl/glow/entity/EntityGlowingData.kt | 73 ---- .../impl/glow/entity/EntityPlayerData.kt | 8 - .../bridges/SurfPaperNmsGlowingBridgeImpl.kt | 60 --- .../server/packet/lore/PacketLoreListener.kt | 388 ------------------ 15 files changed, 20 insertions(+), 940 deletions(-) delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/GlowingPacketListener.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/SurfGlowingApiImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/TeamData.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/block/BlockGlowingData.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/block/BlockPlayerData.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/entity/EntityGlowingData.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/entity/EntityPlayerData.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsGlowingBridgeImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/lore/PacketLoreListener.kt diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt index 9e710f163..6db0e95ef 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt @@ -44,8 +44,11 @@ class V1_21_11NmsProvider : NmsProvider { override fun createItemBridge(): SurfPaperNmsItemBridge = V1_21_11SurfPaperNmsItemBridgeImpl() override fun createNbtBridge(): SurfPaperNmsNbtBridge = V1_21_11SurfPaperNmsNbtBridgeImpl() - override fun createGlowingBridge(): SurfPaperNmsGlowingBridge = - V1_21_11SurfPaperNmsGlowingBridgeImpl() + override fun createGlowingBridge(): SurfPaperNmsGlowingBridge { + val impl = V1_21_11SurfPaperNmsGlowingBridgeImpl() + V1_21_11SurfPaperNmsGlowingBridgeImpl.INSTANCE = impl + return impl + } override fun createStatsBridge(): SurfPaperNmsStatsBridge = V1_21_11SurfPaperNmsStatsBridgeImpl() @@ -85,6 +88,7 @@ class V1_21_11NmsProvider : NmsProvider { override fun createGlowingApi(): SurfGlowingApi { val plugin = JavaPlugin.getProvidingPlugin(V1_21_11NmsProvider::class.java) as JavaPlugin val api = V1_21_11SurfGlowingApiImpl(plugin) + V1_21_11SurfGlowingApiImpl.INSTANCE = api glowingApi = api return api } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsGlowingBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsGlowingBridgeImpl.kt index 81b39f348..1a8849ad3 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsGlowingBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsGlowingBridgeImpl.kt @@ -55,6 +55,7 @@ class V1_21_11SurfPaperNmsGlowingBridgeImpl : SurfPaperNmsGlowingBridge { } companion object { - val INSTANCE get() = SurfPaperNmsGlowingBridge.INSTANCE as V1_21_11SurfPaperNmsGlowingBridgeImpl + lateinit var INSTANCE: V1_21_11SurfPaperNmsGlowingBridgeImpl + internal set } } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11SurfGlowingApiImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11SurfGlowingApiImpl.kt index f3064a2d4..fb0c89154 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11SurfGlowingApiImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11SurfGlowingApiImpl.kt @@ -149,7 +149,8 @@ class V1_21_11SurfGlowingApiImpl(private val plugin: JavaPlugin) : SurfGlowingAp private fun teamIdFor(entity: Entity) = (entity as? Player)?.name ?: entity.uniqueId.toString() companion object { - val INSTANCE get() = SurfGlowingApi.INSTANCE as V1_21_11SurfGlowingApiImpl + lateinit var INSTANCE: V1_21_11SurfGlowingApiImpl + internal set private val entityPlayerData = ConcurrentHashMap() private val blockPlayerData = ConcurrentHashMap() diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt index 6b1170aec..a58acb187 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt @@ -44,8 +44,11 @@ class V26_1NmsProvider : NmsProvider { override fun createItemBridge(): SurfPaperNmsItemBridge = V26_1SurfPaperNmsItemBridgeImpl() override fun createNbtBridge(): SurfPaperNmsNbtBridge = V26_1SurfPaperNmsNbtBridgeImpl() - override fun createGlowingBridge(): SurfPaperNmsGlowingBridge = - V26_1SurfPaperNmsGlowingBridgeImpl() + override fun createGlowingBridge(): SurfPaperNmsGlowingBridge { + val impl = V26_1SurfPaperNmsGlowingBridgeImpl() + V26_1SurfPaperNmsGlowingBridgeImpl.INSTANCE = impl + return impl + } override fun createStatsBridge(): SurfPaperNmsStatsBridge = V26_1SurfPaperNmsStatsBridgeImpl() override fun createLootTableBridge(): SurfPaperNmsLootTableBridge = @@ -81,6 +84,7 @@ class V26_1NmsProvider : NmsProvider { override fun createGlowingApi(): SurfGlowingApi { val plugin = JavaPlugin.getProvidingPlugin(V26_1NmsProvider::class.java) as JavaPlugin val api = V26_1SurfGlowingApiImpl(plugin) + V26_1SurfGlowingApiImpl.INSTANCE = api glowingApi = api return api } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsGlowingBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsGlowingBridgeImpl.kt index 1c081816e..dc055d9e8 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsGlowingBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsGlowingBridgeImpl.kt @@ -55,6 +55,7 @@ class V26_1SurfPaperNmsGlowingBridgeImpl : SurfPaperNmsGlowingBridge { } companion object { - val INSTANCE get() = SurfPaperNmsGlowingBridge.INSTANCE as V26_1SurfPaperNmsGlowingBridgeImpl + lateinit var INSTANCE: V26_1SurfPaperNmsGlowingBridgeImpl + internal set } } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt index ed9b248d1..e7f9d91a7 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt @@ -149,7 +149,8 @@ class V26_1SurfGlowingApiImpl(private val plugin: JavaPlugin) : SurfGlowingApi { private fun teamIdFor(entity: Entity) = (entity as? Player)?.name ?: entity.uniqueId.toString() companion object { - val INSTANCE get() = SurfGlowingApi.INSTANCE as V26_1SurfGlowingApiImpl + lateinit var INSTANCE: V26_1SurfGlowingApiImpl + internal set private val entityPlayerData = ConcurrentHashMap() private val blockPlayerData = ConcurrentHashMap() diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/GlowingPacketListener.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/GlowingPacketListener.kt deleted file mode 100644 index 5645ef977..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/GlowingPacketListener.kt +++ /dev/null @@ -1,99 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.glow - -import com.github.benmanes.caffeine.cache.Caffeine -import com.sksamuel.aedile.core.expireAfterWrite -import dev.slne.surf.api.core.util.mutableObjectListOf -import dev.slne.surf.api.core.util.toMutableObjectList -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.packet.listener.listener.PacketListener -import dev.slne.surf.api.paper.packet.listener.listener.annotation.ClientboundListener -import dev.slne.surf.api.paper.server.reflection.Reflection -import glm_.or -import net.minecraft.network.protocol.Packet -import net.minecraft.network.protocol.game.ClientboundBundlePacket -import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket -import net.minecraft.network.syncher.SynchedEntityData.DataValue -import org.bukkit.entity.Player -import kotlin.time.Duration.Companion.seconds - -@OptIn(NmsUseWithCaution::class) -object GlowingPacketListener : PacketListener { - - val ignoreCache = Caffeine.newBuilder() - .weakKeys() - .expireAfterWrite(5.seconds) - .build, Unit>() - - fun ignorePacket(packet: Packet<*>) { - ignoreCache.put(packet, Unit) - } - - @ClientboundListener - fun onBundlePacket(packet: ClientboundBundlePacket, player: Player): ClientboundBundlePacket { - val bundles = packet.subPackets().toMutableObjectList() - bundles.replaceAll { subPacket -> - if (subPacket is ClientboundSetEntityDataPacket) { - updatePacketIfNeeded(subPacket, player) - } else { - subPacket - } - } - - return ClientboundBundlePacket(bundles) - } - - @ClientboundListener - fun onSetEntityDataPacket( - packet: ClientboundSetEntityDataPacket, - player: Player, - ): ClientboundSetEntityDataPacket { - return updatePacketIfNeeded(packet, player) - } - - private fun updatePacketIfNeeded( - packet: ClientboundSetEntityDataPacket, - player: Player - ): ClientboundSetEntityDataPacket { - // Ignore packets that we don't care about - if (ignoreCache.asMap().remove(packet) != null) { - return packet - } - - val playerData = SurfGlowingApiImpl.getEntityPlayerData(player) ?: return packet - val glowingData = playerData.entities.get(packet.id) ?: return packet - val incoming = packet.packedItems - var flagsFound = false - var edited = false - val newItems = mutableObjectListOf>(incoming.size + 1) - val dataFlagsShared = Reflection.ENTITY_PROXY.getDataFlagsSharedId() - val dataFlagsSharedId = dataFlagsShared.id - - for (dataValue in incoming) { - if (dataValue.id == dataFlagsSharedId) { - flagsFound = true - val current = dataValue.value as Byte - glowingData.otherFlags = current - val withGlow: Byte = current or SurfGlowingApiImpl.glowingFlag - - if (withGlow != current) { - edited = true - newItems.add(DataValue(dataFlagsSharedId, dataFlagsShared.serializer, withGlow)) - } else { - newItems.add(dataValue) - } - } else { - newItems.add(dataValue) - } - } - - if (!edited && !flagsFound) { - val withGlow = glowingData.otherFlags or SurfGlowingApiImpl.glowingFlag - if (withGlow != 0.toByte()) { - edited = true - newItems.add(DataValue(dataFlagsSharedId, dataFlagsShared.serializer, withGlow)) - } - } - - return if (edited) ClientboundSetEntityDataPacket(packet.id, newItems) else packet - } -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/SurfGlowingApiImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/SurfGlowingApiImpl.kt deleted file mode 100644 index 02c4efb00..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/SurfGlowingApiImpl.kt +++ /dev/null @@ -1,173 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.glow - -import com.github.shynixn.mccoroutine.folia.entityDispatcher -import com.github.shynixn.mccoroutine.folia.launch -import dev.slne.surf.api.paper.extensions.server -import dev.slne.surf.api.paper.glow.SurfGlowingApi -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsGlowingBridge -import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation -import dev.slne.surf.api.paper.server.impl.glow.block.BlockGlowingData -import dev.slne.surf.api.paper.server.impl.glow.block.BlockPlayerData -import dev.slne.surf.api.paper.server.impl.glow.entity.EntityGlowingData -import dev.slne.surf.api.paper.server.impl.glow.entity.EntityPlayerData -import dev.slne.surf.api.paper.server.plugin -import dev.slne.surf.api.paper.server.reflection.Reflection -import dev.slne.surf.api.paper.util.isChunkVisible -import io.papermc.paper.adventure.PaperAdventure -import net.kyori.adventure.text.format.NamedTextColor -import org.bukkit.Location -import org.bukkit.block.Block -import org.bukkit.entity.Entity -import org.bukkit.entity.Player -import java.util.* -import java.util.concurrent.ConcurrentHashMap - -class SurfGlowingApiImpl : SurfGlowingApi { - - @OptIn(NmsUseWithCaution::class) - override fun makeGlowing( - target: Entity, - viewer: Player, - color: NamedTextColor?, - ) { - makeGlowing( - target.entityId, - teamIdFor(target), - viewer, - color, - SurfPaperNmsGlowingBridge.getCurrentFlags(target) - ) - } - - override fun makeGlowing( - targetId: Int, - teamId: String, - viewer: Player, - color: NamedTextColor?, - otherFlags: Byte, - ) { - val color = color?.let { PaperAdventure.asVanilla(it) } - val uuid = viewer.uniqueId - val playerData = entityPlayerData.computeIfAbsent(uuid) { EntityPlayerData(uuid) } - val glowingData = playerData.entities.get(targetId) - val operation = PacketOperation.start() - - if (glowingData == null) { - val newData = EntityGlowingData( - playerData, - targetId, - teamId, - color, - otherFlags - ) - playerData.entities.put(targetId, newData) - - operation.add(newData.sendGlowingFlag(enabled = true, ignorePacket = true)) - if (color != null) { - operation.add(newData.sendTeamColor()) - } - operation.execute(viewer) - - return - } - - if (color == glowingData.color) return - if (color == null) { - operation.add(glowingData.removeFromTeam()) - glowingData.color = null - } else { - glowingData.color = color - operation.add(glowingData.sendTeamColor()) - } - - operation.execute(viewer) - } - - override fun makeGlowing(block: Block, viewer: Player, color: NamedTextColor) { - makeGlowing(block.location, viewer, color) - } - - override fun makeGlowing(location: Location, viewer: Player, color: NamedTextColor) { - location.checkFinite() - val location = location.toBlockLocation() - val uuid = viewer.uniqueId - val playerData = blockPlayerData.getOrPut(uuid) { BlockPlayerData(uuid) } - val blockData = playerData.blocks[location] - - if (blockData == null) { - val newData = BlockGlowingData(playerData, location, color) - playerData.blocks[location] = newData - - plugin.launch(plugin.entityDispatcher(viewer)) { - if (viewer.isChunkVisible(location)) { - newData.spawn().execute(viewer) - } - } - } else { - blockData.color = color - blockData.updateColor() - } - } - - override fun removeGlowing(target: Entity, viewer: Player) { - removeGlowing(target.entityId, viewer) - } - - fun removeGlowing(targetId: Int, viewer: UUID) { - val player = server.getPlayer(viewer) - - if (player == null) { - entityPlayerData[viewer]?.entities?.remove(targetId) - } else { - removeGlowing(targetId, player) - } - } - - override fun removeGlowing(targetId: Int, viewer: Player) { - val playerData = entityPlayerData[viewer.uniqueId] ?: return - val glowingData = playerData.entities.remove(targetId) ?: return - val operation = glowingData.sendGlowingFlag(enabled = false) + glowingData.removeFromTeam() - operation.execute(viewer) - } - - override fun removeGlowing(block: Block, viewer: Player) { - removeGlowing(block.location, viewer) - } - - override fun removeGlowing(location: Location, viewer: Player) { - location.checkFinite() - val location = location.toBlockLocation() - val playerData = blockPlayerData[viewer.uniqueId] ?: return - val blockData = playerData.blocks.remove(location) ?: return - - blockData.remove() - if (playerData.blocks.isEmpty()) { - blockPlayerData.remove(viewer.uniqueId) - } - } - - private fun teamIdFor(entity: Entity) = (entity as? Player)?.name ?: entity.uniqueId.toString() - - companion object { - val INSTANCE get() = SurfGlowingApi.INSTANCE as SurfGlowingApiImpl - - private val entityPlayerData = ConcurrentHashMap() - private val blockPlayerData = ConcurrentHashMap() - - val glowingFlag = 1 shl Reflection.ENTITY_PROXY.getFlagGlowing() - - fun getEntityPlayerData(player: Player): EntityPlayerData? = - entityPlayerData[player.uniqueId] - - fun getBlockPlayerData(player: Player): BlockPlayerData? = - blockPlayerData[player.uniqueId] - - fun removeAllGlowingOnQuit(player: Player) { - val uuid = player.uniqueId - TeamData.removeFromAll(uuid) - entityPlayerData.remove(uuid)?.entities?.clear() - blockPlayerData.remove(uuid)?.blocks?.clear() - } - } -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/TeamData.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/TeamData.kt deleted file mode 100644 index b37b29d55..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/TeamData.kt +++ /dev/null @@ -1,40 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.glow - -import net.minecraft.ChatFormatting -import net.minecraft.world.scores.PlayerTeam -import net.minecraft.world.scores.Scoreboard -import net.minecraft.world.scores.Team -import java.util.* -import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.atomic.AtomicInteger - -class TeamData(color: ChatFormatting) { - private val scoreboard = Scoreboard() - val teamId = "glow-${uid()}${color.char}" - val team = PlayerTeam(scoreboard, teamId).apply { - collisionRule = Team.CollisionRule.NEVER - this.color = color - } - - private val seenBy = ConcurrentHashMap.newKeySet() - - fun markSeen(uniqueId: UUID) = seenBy.add(uniqueId) - fun isSeen(uniqueId: UUID): Boolean = seenBy.contains(uniqueId) - fun removeSeen(uniqueId: UUID) = seenBy.remove(uniqueId) - - companion object { - private val lastUid = AtomicInteger() - fun uid(): Int = lastUid.getAndIncrement() - - private val teams = EnumMap(ChatFormatting::class.java) - - fun getByColor(color: ChatFormatting): TeamData = - teams.computeIfAbsent(color) { TeamData(color) } - - fun getByColorOrNull(color: ChatFormatting): TeamData? = teams[color] - - fun removeFromAll(uuid: UUID) { - teams.values.forEach { it.removeSeen(uuid) } - } - } -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/block/BlockGlowingData.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/block/BlockGlowingData.kt deleted file mode 100644 index ef207ea16..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/block/BlockGlowingData.kt +++ /dev/null @@ -1,80 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.glow.block - -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsCommonBridge -import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation -import dev.slne.surf.api.paper.nms.bridges.packets.entity.SurfPaperNmsSpawnPackets -import dev.slne.surf.api.paper.server.impl.glow.SurfGlowingApiImpl -import dev.slne.surf.api.paper.server.impl.nms.bridges.SurfPaperNmsGlowingBridgeImpl -import dev.slne.surf.api.paper.server.impl.nms.bridges.packets.PacketOperationImpl -import dev.slne.surf.api.paper.server.reflection.Reflection -import glm_.shl -import net.kyori.adventure.text.format.NamedTextColor -import net.minecraft.network.protocol.game.ClientboundAddEntityPacket -import net.minecraft.world.entity.EntityType -import net.minecraft.world.phys.Vec3 -import org.bukkit.Location -import java.util.* - -@OptIn(NmsUseWithCaution::class) -class BlockGlowingData( - val playerData: BlockPlayerData, - val location: Location, - var color: NamedTextColor, -) { - - private val entityId: Int by lazy { SurfPaperNmsCommonBridge.nextEntityId() } - private val uuid: UUID by lazy { UUID.randomUUID() } - private var initialized = false - - fun spawn(): PacketOperation { - initialize() - - val spawnOperation = PacketOperationImpl.simple { - ClientboundAddEntityPacket( - entityId, - uuid, - location.x, - location.y, - location.z, - location.pitch, - location.yaw, - EntityType.SHULKER, - 0, - Vec3.ZERO, - 0.0 - ) - } - val invisibleOperation = SurfPaperNmsGlowingBridgeImpl.INSTANCE - .setEntityFlags(entityId, invisibleFlag) - - return spawnOperation + invisibleOperation - } - - - fun updateColor() { - val player = playerData.player ?: return - SurfGlowingApiImpl.INSTANCE.makeGlowing( - entityId, - uuid.toString(), - player, - color, - invisibleFlag - ) - } - - fun remove() { - playerData.player?.let { SurfPaperNmsSpawnPackets.despawn(entityId).execute(it) } - SurfGlowingApiImpl.INSTANCE.removeGlowing(entityId, playerData.uuid) - } - - private fun initialize() { - if (initialized) return - initialized = true - updateColor() - } - - companion object { - val invisibleFlag = 1.toByte() shl Reflection.ENTITY_PROXY.getFlagInvisible() - } -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/block/BlockPlayerData.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/block/BlockPlayerData.kt deleted file mode 100644 index 0af3d594f..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/block/BlockPlayerData.kt +++ /dev/null @@ -1,11 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.glow.block - -import dev.slne.surf.api.core.util.mutableObject2ObjectMapOf -import dev.slne.surf.api.paper.extensions.server -import org.bukkit.Location -import java.util.* - -class BlockPlayerData(val uuid: UUID) { - val blocks = mutableObject2ObjectMapOf() - val player get() = server.getPlayer(uuid) -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/entity/EntityGlowingData.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/entity/EntityGlowingData.kt deleted file mode 100644 index 05e945d1e..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/entity/EntityGlowingData.kt +++ /dev/null @@ -1,73 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.glow.entity - -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation -import dev.slne.surf.api.paper.server.impl.glow.SurfGlowingApiImpl -import dev.slne.surf.api.paper.server.impl.glow.TeamData -import dev.slne.surf.api.paper.server.impl.nms.bridges.SurfPaperNmsGlowingBridgeImpl -import dev.slne.surf.api.paper.server.impl.nms.bridges.packets.PacketOperationImpl -import glm_.and -import glm_.or -import net.minecraft.ChatFormatting - -data class EntityGlowingData( - val playerData: EntityPlayerData, - val entityId: Int, - val teamId: String, - var color: ChatFormatting?, - var otherFlags: Byte, -) { - - @OptIn(NmsUseWithCaution::class) - fun sendTeamColor(): PacketOperation { - val color = color ?: return PacketOperationImpl.empty() - val teamData = TeamData.getByColor(color) - - val operation = PacketOperation.start() - if (teamData.markSeen(playerData.uuid)) { - operation.add(SurfPaperNmsGlowingBridgeImpl.INSTANCE.createTeam(teamData)) - } - operation.add(SurfPaperNmsGlowingBridgeImpl.INSTANCE.addEntityToTeam(teamData, teamId)) - - return operation - } - - @OptIn(NmsUseWithCaution::class) - fun removeFromTeam(): PacketOperation { - val color = color ?: return PacketOperationImpl.empty() - val teamData = TeamData.getByColorOrNull(color) ?: return PacketOperationImpl.empty() - - val operation = PacketOperation.start() - if (teamData.removeSeen(playerData.uuid)) { - operation.add( - SurfPaperNmsGlowingBridgeImpl.INSTANCE.removeEntityFromTeam( - teamData, - teamId - ) - ) - } - - return operation - } - - @OptIn(NmsUseWithCaution::class) - fun sendGlowingFlag(enabled: Boolean, ignorePacket: Boolean = false): PacketOperation { - val newFlags = if (enabled) { - otherFlags or SurfGlowingApiImpl.glowingFlag - } else { - otherFlags and SurfGlowingApiImpl.glowingFlag.inv() - } - - return SurfPaperNmsGlowingBridgeImpl.INSTANCE.setEntityFlags( - entityId, - newFlags, - ignorePacket - ) - } - - fun computeFlags(): Byte { - return (otherFlags and SurfGlowingApiImpl.glowingFlag.inv()).or( - if (color != null) SurfGlowingApiImpl.glowingFlag else 0 - ) - } -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/entity/EntityPlayerData.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/entity/EntityPlayerData.kt deleted file mode 100644 index 63c1433bb..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/entity/EntityPlayerData.kt +++ /dev/null @@ -1,8 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.glow.entity - -import java.util.* -import java.util.concurrent.ConcurrentHashMap - -data class EntityPlayerData(val uuid: UUID) { - val entities = ConcurrentHashMap() -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsGlowingBridgeImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsGlowingBridgeImpl.kt deleted file mode 100644 index 1fc74c7b3..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsGlowingBridgeImpl.kt +++ /dev/null @@ -1,60 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.bridges - -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsGlowingBridge -import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation -import dev.slne.surf.api.paper.server.impl.glow.GlowingPacketListener -import dev.slne.surf.api.paper.server.impl.glow.TeamData -import dev.slne.surf.api.paper.server.impl.nms.bridges.packets.PacketOperationImpl -import dev.slne.surf.api.paper.server.nms.toNms -import dev.slne.surf.api.paper.server.reflection.Reflection -import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket -import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket -import net.minecraft.network.syncher.SynchedEntityData.DataValue -import org.bukkit.entity.Entity - -@NmsUseWithCaution -class SurfPaperNmsGlowingBridgeImpl : SurfPaperNmsGlowingBridge { - fun createTeam(data: TeamData): PacketOperation = - PacketOperationImpl.simple { - ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(data.team, true) - } - - fun addEntityToTeam(data: TeamData, entry: String): PacketOperation = - PacketOperationImpl.simple { - ClientboundSetPlayerTeamPacket.createPlayerPacket( - data.team, - entry, - ClientboundSetPlayerTeamPacket.Action.ADD - ) - } - - fun removeEntityFromTeam(data: TeamData, entry: String): PacketOperation = - PacketOperationImpl.simple { - ClientboundSetPlayerTeamPacket.createPlayerPacket( - data.team, - entry, - ClientboundSetPlayerTeamPacket.Action.REMOVE - ) - } - - fun setEntityFlags(entityId: Int, flags: Byte, ignorePacket: Boolean = false): PacketOperation = - PacketOperationImpl.simple { - val dataAccessor = Reflection.ENTITY_PROXY.getDataFlagsSharedId() - val data = DataValue(dataAccessor.id(), dataAccessor.serializer, flags) - ClientboundSetEntityDataPacket(entityId, listOf(data)).also { - if (ignorePacket) { - GlowingPacketListener.ignorePacket(it) - } - } - } - - override fun getCurrentFlags(entity: Entity): Byte { - val dataAccessor = Reflection.ENTITY_PROXY.getDataFlagsSharedId() - return entity.toNms().entityData.get(dataAccessor) - } - - companion object { - val INSTANCE get() = SurfPaperNmsGlowingBridge.INSTANCE as SurfPaperNmsGlowingBridgeImpl - } -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/lore/PacketLoreListener.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/lore/PacketLoreListener.kt deleted file mode 100644 index 475134c82..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/lore/PacketLoreListener.kt +++ /dev/null @@ -1,388 +0,0 @@ -package dev.slne.surf.api.paper.server.packet.lore - -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.packet.listener.listener.PacketListener -import dev.slne.surf.api.paper.packet.listener.listener.annotation.ClientboundListener -import dev.slne.surf.api.paper.packet.listener.listener.annotation.ServerboundListener -import dev.slne.surf.api.paper.packet.lore.SurfPaperPacketLoreHandler -import dev.slne.surf.api.paper.server.nms.toBukkit -import dev.slne.surf.api.paper.server.nms.toNms -import dev.slne.surf.api.paper.util.namespacedKey -import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap -import it.unimi.dsi.fastutil.objects.ObjectArrayList -import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet -import it.unimi.dsi.fastutil.objects.ObjectLists -import net.kyori.adventure.text.format.TextDecoration -import net.minecraft.core.component.DataComponents -import net.minecraft.network.protocol.game.* -import net.minecraft.server.level.ServerPlayer -import net.minecraft.world.item.ItemStack -import net.minecraft.world.item.component.CustomData -import net.minecraft.world.item.component.ItemLore -import org.bukkit.NamespacedKey -import org.bukkit.plugin.Plugin -import net.minecraft.network.chat.Component as MinecraftComponent - -/** - * PacketLoreListener is a class that implements PacketListenerAbstract and is responsible for - * handling the modification of lore on item stacks in packet events. - */ -@OptIn(NmsUseWithCaution::class) -object PacketLoreListener : PacketListener { - private val globalHandlersByPlugin = - Object2ObjectLinkedOpenHashMap>() - - private val keyedHandlersByPlugin = - Object2ObjectLinkedOpenHashMap>() - - @Volatile - private var keyedHandlersSnapshot: Map = emptyMap() - - @Volatile - private var globalHandlersSnapshot: Array = emptyArray() - - private val ORIGINAL_LORE_KEY = namespacedKey("original_lore") - private val ORIGINAL_LORE_KEY_STRING = ORIGINAL_LORE_KEY.asString() - - private fun hasAnyHandlers(): Boolean = - keyedHandlersSnapshot.isNotEmpty() || globalHandlersSnapshot.isNotEmpty() - - @ServerboundListener - fun onPacketReceive(event: ServerboundSetCreativeModeSlotPacket) { - makeCleanItemStack(event.itemStack()) - } - - @ClientboundListener - fun onWindowItem(event: ClientboundContainerSetContentPacket): ClientboundContainerSetContentPacket { - if (!hasAnyHandlers()) return event - - val sourceItems = event.items - val updatedItems = ObjectArrayList(sourceItems.size) - - var changed = false - - for (i in sourceItems.indices) { - val original = sourceItems[i] - val updated = makeUpdatedItemStack(original) - - if (updated !== original) { - changed = true - } - - updatedItems.add(updated) - } - - val originalCarried = event.carriedItem() - val updatedCarried = makeUpdatedItemStack(originalCarried) - - if (updatedCarried !== originalCarried) { - changed = true - } - - if (!changed) { - return event - } - - return ClientboundContainerSetContentPacket( - event.containerId(), - event.stateId(), - updatedItems, - updatedCarried - ) - } - - @ClientboundListener - fun onSetSlotPacket(event: ClientboundContainerSetSlotPacket): ClientboundContainerSetSlotPacket { - val original = event.item - val updated = makeUpdatedItemStack(original) - - if (updated === original) { - return event - } - - return ClientboundContainerSetSlotPacket( - event.containerId, - event.stateId, - event.slot, - updated - ) - } - - @ClientboundListener - fun onSetPlayerInventoryPacket(event: ClientboundSetPlayerInventoryPacket): ClientboundSetPlayerInventoryPacket { - val original = event.contents - val updated = makeUpdatedItemStack(original) - - if (updated === original) { - return event - } - - return ClientboundSetPlayerInventoryPacket( - event.slot(), - updated - ) - } - - @ServerboundListener - fun onContainerClickPacket( - event: ServerboundContainerClickPacket, - player: ServerPlayer - ): ServerboundContainerClickPacket { - if (!hasAnyHandlers()) return event - - val container = player.containerMenu - val currentStateId = container.stateId - - val brokenStateId = if (event.stateId() == currentStateId) { - currentStateId - 1 - } else { - event.stateId() - } - - if (brokenStateId == event.stateId()) return event - - return ServerboundContainerClickPacket( - event.containerId(), - brokenStateId, - event.slotNum(), - event.buttonNum(), - event.containerInput(), - event.changedSlots(), - event.carriedItem() - ) - } - - @ClientboundListener - fun onSetCursorItemPacket(event: ClientboundSetCursorItemPacket): ClientboundSetCursorItemPacket { - val original = event.contents - val updated = makeUpdatedItemStack(original) - - if (updated === original) { - return event - } - - return ClientboundSetCursorItemPacket(updated) - } - - /** - * Returns the original item if: - * - item is empty - * - no handlers exist - * - no keyed handler matches and no global handler exists - * - handlers run but lore result is identical - * - * Only copies the stack if at least one handler will actually run. - */ - private fun makeUpdatedItemStack( - original: ItemStack, - ): ItemStack { - if (original.isEmpty) return original - - // One volatile read - val keyedSnapshot = keyedHandlersSnapshot - val globalSnapshot = globalHandlersSnapshot - - if (keyedSnapshot.isEmpty() && globalSnapshot.isEmpty()) { - return original - } - - /* - * We need Bukkit PDC for the current handler API, but only when there - * are keyed handlers to consider. The original mirror is used to cheaply - * determine whether any keyed handlers actually match. - */ - val matchingKeyedHandlers = if (keyedSnapshot.isNotEmpty()) { - val originalBukkitStack = original.asBukkitMirror() - val originalPdc = originalBukkitStack.persistentDataContainer - resolveMatchingKeyedHandlers( - originalPdc.keys, - keyedSnapshot - ) - } else { - ObjectLists.emptyList() - } - - if (matchingKeyedHandlers.isEmpty() && globalSnapshot.isEmpty()) { - return original - } - - /* - * From here on, we know that at least one handler will run. - * Only now create a copy. - */ - val item = original.copy() - val bukkitStack = item.asBukkitMirror() - val pdc = bukkitStack.persistentDataContainer - - val originalLore = item.getOrDefault(DataComponents.LORE, ItemLore.EMPTY) - val originalLines = originalLore.lines - - val mutableLore = originalLines.mapTo( - ObjectArrayList(originalLines.size) - ) { it.toBukkit() } - - for (i in matchingKeyedHandlers.indices) { - matchingKeyedHandlers[i].handleLore(mutableLore, pdc, bukkitStack) - } - - for (i in globalSnapshot.indices) { - globalSnapshot[i].handleLore(mutableLore, pdc, bukkitStack) - } - - val updatedLines = ObjectArrayList(mutableLore.size) - for (i in mutableLore.indices) { - val line = - mutableLore[i].decorationIfAbsent(TextDecoration.ITALIC, TextDecoration.State.FALSE) - updatedLines.add(line.toNms()) - } - - val updatedLore = ItemLore(updatedLines) - - if (updatedLore == originalLore) { - return original - } - - item.set(DataComponents.LORE, updatedLore) - CustomData.update(DataComponents.CUSTOM_DATA, item) { tag -> - if (!tag.contains(ORIGINAL_LORE_KEY_STRING)) { - tag.store(ORIGINAL_LORE_KEY_STRING, ItemLore.CODEC, originalLore) - } - } - - return item - } - - private fun makeCleanItemStack( - stack: ItemStack, - ): ItemStack { - if (stack.isEmpty) { - return stack - } - - val customData = stack.get(DataComponents.CUSTOM_DATA) ?: return stack - if (!customData.contains(ORIGINAL_LORE_KEY_STRING)) { - return stack - } - - CustomData.update(DataComponents.CUSTOM_DATA, stack) { tag -> - val originalLore = tag.read(ORIGINAL_LORE_KEY_STRING, ItemLore.CODEC) - originalLore.ifPresent { lore -> - stack.set(DataComponents.LORE, lore) - tag.remove(ORIGINAL_LORE_KEY_STRING) - } - } - - return stack - } - - private fun resolveMatchingKeyedHandlers( - itemKeys: Set, - keyedSnapshot: Map, - ): List { - if (itemKeys.isEmpty() || keyedSnapshot.isEmpty()) { - return emptyList() - } - - var result: ObjectArrayList? = null - for (key in itemKeys) { - val handler = keyedSnapshot[key] ?: continue - - if (result == null) { - result = ObjectArrayList(2) - } - - result.add(handler) - } - - return result ?: emptyList() - } - - fun register(plugin: Plugin, identifier: NamespacedKey, listener: SurfPaperPacketLoreHandler) { - synchronized(this) { - check(!keyedHandlersSnapshot.containsKey(identifier)) { - "A PacketLore handler for $identifier is already registered!" - } - - val handlers = - keyedHandlersByPlugin.computeIfAbsent(plugin) { Object2ObjectLinkedOpenHashMap() } - - val previous = handlers.putIfAbsent(identifier, listener) - check(previous == null) { - "A PacketLore handler for $identifier is already registered for plugin ${plugin.name}!" - } - - val newSnapshot = Object2ObjectLinkedOpenHashMap(keyedHandlersSnapshot) - newSnapshot[identifier] = listener - keyedHandlersSnapshot = newSnapshot - } - } - - fun register(plugin: Plugin, listener: SurfPaperPacketLoreHandler) { - synchronized(this) { - val handlers = - globalHandlersByPlugin.computeIfAbsent(plugin) { ObjectLinkedOpenHashSet() } - if (handlers.add(listener)) { - rebuildGlobalHandlersSnapshot() - } else { - error("A PacketLore handler identical to the provided one (${listener.javaClass.name}) is already registered for plugin ${plugin.name}!") - } - } - } - - fun unregister(identifier: NamespacedKey) { - synchronized(this) { - if (!keyedHandlersSnapshot.containsKey(identifier)) { - return - } - - var emptyPlugin: Plugin? = null - - for ((plugin, handlers) in keyedHandlersByPlugin) { - if (handlers.remove(identifier) != null) { - if (handlers.isEmpty()) { - emptyPlugin = plugin - } - break - } - } - - if (emptyPlugin != null) { - keyedHandlersByPlugin.remove(emptyPlugin) - } - - val newSnapshot = Object2ObjectLinkedOpenHashMap(keyedHandlersSnapshot) - newSnapshot.remove(identifier) - keyedHandlersSnapshot = newSnapshot - } - } - - fun unregister(plugin: Plugin) { - synchronized(this) { - val removedGlobal = globalHandlersByPlugin.remove(plugin) != null - if (removedGlobal) { - rebuildGlobalHandlersSnapshot() - } - - val removedKeyed = keyedHandlersByPlugin.remove(plugin) - if (removedKeyed != null) { - val newSnapshot = Object2ObjectLinkedOpenHashMap(keyedHandlersSnapshot) - for (identifier in removedKeyed.keys) { - newSnapshot.remove(identifier) - } - keyedHandlersSnapshot = newSnapshot - } - } - } - - private fun rebuildGlobalHandlersSnapshot() { - val snapshot = ObjectArrayList() - - globalHandlersByPlugin.object2ObjectEntrySet().fastForEach { (plugin, handlers) -> - if (plugin.isEnabled) { - snapshot.addAll(handlers) - } - } - - globalHandlersSnapshot = snapshot.toTypedArray() - } -} From 6771b662c67903efb17b4e49dc3b8a78aefa983e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 15 Apr 2026 06:17:31 +0000 Subject: [PATCH 16/34] fix: ensure glowing bridge INSTANCE is initialized before glowing API uses it Cache the bridge instance in NmsProvider and call createGlowingBridge() at the start of createGlowingApi() to guarantee the bridge INSTANCE is always set before the API can use it. Applied to both V1_21_11NmsProvider and V26_1NmsProvider. Agent-Logs-Url: https://github.com/SLNE-Development/surf-api/sessions/f67fef39-1e25-4d4b-83e2-56ff14f551ac Co-authored-by: TheBjoRedCraft <143264463+TheBjoRedCraft@users.noreply.github.com> --- .../paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt | 11 ++++++++--- .../api/paper/server/nms/v26_1/V26_1NmsProvider.kt | 11 ++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt index 6db0e95ef..01e81f9a2 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt @@ -33,6 +33,7 @@ import org.bukkit.plugin.java.JavaPlugin class V1_21_11NmsProvider : NmsProvider { override val version: NmsVersion = NmsVersion.V1_21_11 + private var glowingBridge: V1_21_11SurfPaperNmsGlowingBridgeImpl? = null private var glowingApi: V1_21_11SurfGlowingApiImpl? = null override fun createNmsBridge(): SurfPaperNmsBridge = V1_21_11SurfPaperNmsBridgeImpl() @@ -45,9 +46,10 @@ class V1_21_11NmsProvider : NmsProvider { override fun createItemBridge(): SurfPaperNmsItemBridge = V1_21_11SurfPaperNmsItemBridgeImpl() override fun createNbtBridge(): SurfPaperNmsNbtBridge = V1_21_11SurfPaperNmsNbtBridgeImpl() override fun createGlowingBridge(): SurfPaperNmsGlowingBridge { - val impl = V1_21_11SurfPaperNmsGlowingBridgeImpl() - V1_21_11SurfPaperNmsGlowingBridgeImpl.INSTANCE = impl - return impl + return glowingBridge ?: V1_21_11SurfPaperNmsGlowingBridgeImpl().also { + glowingBridge = it + V1_21_11SurfPaperNmsGlowingBridgeImpl.INSTANCE = it + } } override fun createStatsBridge(): SurfPaperNmsStatsBridge = @@ -86,6 +88,9 @@ class V1_21_11NmsProvider : NmsProvider { V1_21_11GlowingLifecycleHandler() override fun createGlowingApi(): SurfGlowingApi { + // Ensure glowing bridge is initialized before the API uses it + createGlowingBridge() + val plugin = JavaPlugin.getProvidingPlugin(V1_21_11NmsProvider::class.java) as JavaPlugin val api = V1_21_11SurfGlowingApiImpl(plugin) V1_21_11SurfGlowingApiImpl.INSTANCE = api diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt index a58acb187..0eaa9e551 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt @@ -33,6 +33,7 @@ import org.bukkit.plugin.java.JavaPlugin class V26_1NmsProvider : NmsProvider { override val version: NmsVersion = NmsVersion.V26_1 + private var glowingBridge: V26_1SurfPaperNmsGlowingBridgeImpl? = null private var glowingApi: V26_1SurfGlowingApiImpl? = null override fun createNmsBridge(): SurfPaperNmsBridge = V26_1SurfPaperNmsBridgeImpl() @@ -45,9 +46,10 @@ class V26_1NmsProvider : NmsProvider { override fun createItemBridge(): SurfPaperNmsItemBridge = V26_1SurfPaperNmsItemBridgeImpl() override fun createNbtBridge(): SurfPaperNmsNbtBridge = V26_1SurfPaperNmsNbtBridgeImpl() override fun createGlowingBridge(): SurfPaperNmsGlowingBridge { - val impl = V26_1SurfPaperNmsGlowingBridgeImpl() - V26_1SurfPaperNmsGlowingBridgeImpl.INSTANCE = impl - return impl + return glowingBridge ?: V26_1SurfPaperNmsGlowingBridgeImpl().also { + glowingBridge = it + V26_1SurfPaperNmsGlowingBridgeImpl.INSTANCE = it + } } override fun createStatsBridge(): SurfPaperNmsStatsBridge = V26_1SurfPaperNmsStatsBridgeImpl() @@ -82,6 +84,9 @@ class V26_1NmsProvider : NmsProvider { V26_1GlowingLifecycleHandler() override fun createGlowingApi(): SurfGlowingApi { + // Ensure glowing bridge is initialized before the API uses it + createGlowingBridge() + val plugin = JavaPlugin.getProvidingPlugin(V26_1NmsProvider::class.java) as JavaPlugin val api = V26_1SurfGlowingApiImpl(plugin) V26_1SurfGlowingApiImpl.INSTANCE = api From 9ff57de0bc0ca690c813ef206a3186d96f1ea2b8 Mon Sep 17 00:00:00 2001 From: twisti <76837088+twisti-dev@users.noreply.github.com> Date: Wed, 15 Apr 2026 14:55:17 +0200 Subject: [PATCH 17/34] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(nms):=20rem?= =?UTF-8?q?ove=20unused=20file=20transformers=20for=20NMS=20version=20hand?= =?UTF-8?q?ling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - eliminate fileTransformers for clearDialogs in NmsVersionConfigs.kt - restore clearDialogs implementation in V1_21_11SurfPaperNmsCommonBridgeImpl.kt --- .../surf/api/gen/nms/NmsVersionConfigs.kt | 24 +------------------ .../V1_21_11SurfPaperNmsCommonBridgeImpl.kt | 9 ++++++- 2 files changed, 9 insertions(+), 24 deletions(-) diff --git a/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsVersionConfigs.kt b/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsVersionConfigs.kt index d02540635..746c4225d 100644 --- a/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsVersionConfigs.kt +++ b/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsVersionConfigs.kt @@ -50,29 +50,7 @@ object NmsVersionConfigs { // TypedEntityData → CustomData.of "TypedEntityData.decodeEntity(nbt)" to "CustomData.of(nbt)", ), - fileTransformers = mapOf( - // The CommonBridge needs special handling for clearDialogs (no dialog support in 1.21.11) - "dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsCommonBridgeImpl.kt" to { content -> - content - // Remove dialog-related imports - .replace("import dev.slne.surf.api.paper.dialog.noticeDialogWithBuilder\n", "") - .replace("import net.minecraft.network.protocol.common.ClientboundClearDialogPacket\n", "") - .replace("import net.kyori.adventure.text.Component\n", "") - // Replace clearDialogs implementation with no-op - .replace( - """ override fun clearDialogs(player: Player, showEmptyDialogBefore: Boolean) { - if (showEmptyDialogBefore) { - player.showDialog(noticeDialogWithBuilder(Component.empty()) {}) - } - - player.toNms().connection.send(ClientboundClearDialogPacket.INSTANCE) - }""", - """ override fun clearDialogs(player: Player, showEmptyDialogBefore: Boolean) { - // Dialogs are not supported in 1.21.11 - }""" - ) - }, - ), + fileTransformers = mapOf(), ) /** All target versions that should be generated from the reference. */ diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsCommonBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsCommonBridgeImpl.kt index e1552d58b..4bf87f50f 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsCommonBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsCommonBridgeImpl.kt @@ -1,5 +1,6 @@ package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges +import dev.slne.surf.api.paper.dialog.noticeDialogWithBuilder import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsCommonBridge import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNms @@ -7,6 +8,8 @@ import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNmsBlock import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNmsItem import dev.slne.surf.api.paper.server.nms.v1_21_11.reflection.V1_21_11Reflection import io.papermc.paper.configuration.GlobalConfiguration +import net.kyori.adventure.text.Component +import net.minecraft.network.protocol.common.ClientboundClearDialogPacket import net.minecraft.server.MinecraftServer import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.ComposterBlock @@ -68,7 +71,11 @@ class V1_21_11SurfPaperNmsCommonBridgeImpl : SurfPaperNmsCommonBridge { } override fun clearDialogs(player: Player, showEmptyDialogBefore: Boolean) { - // Dialogs are not supported in 1.21.11 + if (showEmptyDialogBefore) { + player.showDialog(noticeDialogWithBuilder(Component.empty()) {}) + } + + player.toNms().connection.send(ClientboundClearDialogPacket.INSTANCE) } override fun getServerIp(): InetSocketAddress { From 72e23a3c71564dd79d1519aad7aa2c2879995e07 Mon Sep 17 00:00:00 2001 From: twisti <76837088+twisti-dev@users.noreply.github.com> Date: Wed, 15 Apr 2026 16:20:51 +0200 Subject: [PATCH 18/34] =?UTF-8?q?=E2=9C=A8=20feat(nms):=20add=20multiversi?= =?UTF-8?q?on=20support=20with=20NMS=20module=20generator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - introduce a new Gradle plugin for generating NMS modules - implement DSL for configuring reference and target versions - add transformation rules for source code during generation - create tasks for generating NMS modules with user prompts --- build.gradle.kts | 7 + settings.gradle.kts | 1 + surf-api-generator/build.gradle.kts | 8 - .../build.gradle.kts | 16 ++ .../settings.gradle.kts | 2 + .../generator/nms/GenerateNmsModulePlugin.kt | 44 ++++ .../generator/nms/GenerateNmsModuleTask.kt | 87 +++++++ .../surf/api/generator/nms/NmsGeneratorDsl.kt | 7 + .../generator/nms/NmsGeneratorExtension.kt | 40 +++ .../api/generator/nms/NmsModuleGenerator.kt | 234 ++++++++++++++++++ .../api/generator/nms/NmsTransformation.kt | 70 ++++++ .../slne/surf/api/generator/nms/NmsVersion.kt | 42 ++++ .../api/generator/nms/TransformationScope.kt | 56 +++++ .../slne/surf/api/gen/nms/NmsGeneratorMain.kt | 30 --- .../surf/api/gen/nms/NmsTemplateGenerator.kt | 152 ------------ .../slne/surf/api/gen/nms/NmsVersionConfig.kt | 20 -- .../surf/api/gen/nms/NmsVersionConfigs.kt | 58 ----- 17 files changed, 606 insertions(+), 268 deletions(-) create mode 100644 surf-api-generator/gradle-nms-module-generator/build.gradle.kts create mode 100644 surf-api-generator/gradle-nms-module-generator/settings.gradle.kts create mode 100644 surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/GenerateNmsModulePlugin.kt create mode 100644 surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/GenerateNmsModuleTask.kt create mode 100644 surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/NmsGeneratorDsl.kt create mode 100644 surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/NmsGeneratorExtension.kt create mode 100644 surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/NmsModuleGenerator.kt create mode 100644 surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/NmsTransformation.kt create mode 100644 surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/NmsVersion.kt create mode 100644 surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/TransformationScope.kt delete mode 100644 surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsGeneratorMain.kt delete mode 100644 surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsTemplateGenerator.kt delete mode 100644 surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsVersionConfig.kt delete mode 100644 surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsVersionConfigs.kt diff --git a/build.gradle.kts b/build.gradle.kts index 0f648f8a0..07fd07fb0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,8 +2,15 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinJvmExtension plugins { id("io.papermc.paperweight.userdev") version "2.0.0-beta.21" apply false + id("dev.slne.surf.api.generator.nms-module-generator") } +//nmsGenerator { +// referenceVersion = NmsVersion.V26_1 +// targetVersion = NmsVersion.V1_21_11 +//} + + allprojects { repositories { mavenCentral() diff --git a/settings.gradle.kts b/settings.gradle.kts index 54595079b..9c688c3a4 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -3,6 +3,7 @@ pluginManagement { mavenLocal() gradlePluginPortal() } + includeBuild("surf-api-generator/gradle-nms-module-generator") } plugins { diff --git a/surf-api-generator/build.gradle.kts b/surf-api-generator/build.gradle.kts index d808e0f5c..a0e1ef887 100644 --- a/surf-api-generator/build.gradle.kts +++ b/surf-api-generator/build.gradle.kts @@ -105,15 +105,7 @@ tasks.register("generate") { args(projectDir.toPath().resolve("generated").toString()) } -tasks.register("generateNms") { - group = "generation" - description = "Generate version-specific NMS modules from the reference (v26-1) sources" - dependsOn(tasks.classes) - mainClass.set("dev.slne.surf.api.gen.nms.NmsGeneratorMainKt") - classpath(sourceSets.main.map { it.runtimeClasspath }) - args(rootProject.projectDir.absolutePath) -} private fun String.downloadTo(output: Path) { diff --git a/surf-api-generator/gradle-nms-module-generator/build.gradle.kts b/surf-api-generator/gradle-nms-module-generator/build.gradle.kts new file mode 100644 index 000000000..f2655ca68 --- /dev/null +++ b/surf-api-generator/gradle-nms-module-generator/build.gradle.kts @@ -0,0 +1,16 @@ +plugins { + `kotlin-dsl` +} + +repositories { + gradlePluginPortal() +} + +gradlePlugin { + plugins { + create("nms-module-generator") { + id = "dev.slne.surf.api.generator.nms-module-generator" + implementationClass = "dev.slne.surf.api.generator.nms.GenerateNmsModulePlugin" + } + } +} \ No newline at end of file diff --git a/surf-api-generator/gradle-nms-module-generator/settings.gradle.kts b/surf-api-generator/gradle-nms-module-generator/settings.gradle.kts new file mode 100644 index 000000000..bfce74418 --- /dev/null +++ b/surf-api-generator/gradle-nms-module-generator/settings.gradle.kts @@ -0,0 +1,2 @@ +rootProject.name = "gradle-nms-module-generator" + diff --git a/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/GenerateNmsModulePlugin.kt b/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/GenerateNmsModulePlugin.kt new file mode 100644 index 000000000..166b5c961 --- /dev/null +++ b/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/GenerateNmsModulePlugin.kt @@ -0,0 +1,44 @@ +package dev.slne.surf.api.generator.nms + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.register + +/** + * Gradle plugin that registers the `nmsGenerator` extension and the + * `generateNmsModule` task. + * + * Apply the plugin and configure it in `build.gradle.kts`: + * + * ```kotlin + * plugins { + * id("dev.slne.surf.api.generator.nms-module-generator") + * } + * + * nmsGenerator { + * referenceVersion = NmsVersion.V26_1 + * targetVersion = NmsVersion.V1_21_11 + * + * transformations { + * renameClass("net.minecraft.resources.Identifier", + * "net.minecraft.resources.ResourceLocation") + * removeImport("net.minecraft.world.item.component.TypedEntityData") + * replaceCode("TypedEntityData.decodeEntity(nbt)", "CustomData.of(nbt)") + * } + * } + * ``` + * + * Then run: + * ``` + * ./gradlew generateNmsModule # interactive — asks before overwriting + * ./gradlew generateNmsModule -PforceOverwrite # non-interactive + * ``` + */ +abstract class GenerateNmsModulePlugin : Plugin { + override fun apply(target: Project) { + target.extensions.create("nmsGenerator") + target.tasks.register("generateNmsModule") + } +} + diff --git a/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/GenerateNmsModuleTask.kt b/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/GenerateNmsModuleTask.kt new file mode 100644 index 000000000..962d0e6a3 --- /dev/null +++ b/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/GenerateNmsModuleTask.kt @@ -0,0 +1,87 @@ +package dev.slne.surf.api.generator.nms + +import org.gradle.api.DefaultTask +import org.gradle.api.GradleException +import org.gradle.api.tasks.TaskAction +import java.nio.file.Path +import kotlin.io.path.exists + +/** + * Generates a single NMS module from the configured reference version. + * + * If the target module already contains sources the task asks for + * confirmation before overwriting. Pass `-PforceOverwrite` to skip + * the prompt (useful in scripts or CI). + */ +abstract class GenerateNmsModuleTask : DefaultTask() { + + init { + group = "generation" + description = "Generates an NMS module from the reference version sources" + } + + @TaskAction + fun generate() { + val ext = project.extensions.getByType(NmsGeneratorExtension::class.java) + + check(ext.isConfigured) { + "nmsGenerator.referenceVersion and nmsGenerator.targetVersion must be set" + } + + val reference = ext.referenceVersion + val target = ext.targetVersion + val repoRoot = project.rootProject.projectDir.toPath() + + confirmOverwriteIfNeeded(repoRoot, target) + + logger.lifecycle("Generating NMS module: {} -> {} ...", reference.name, target.name) + + val generated = NmsModuleGenerator( + reference = reference, + target = target, + transformations = ext.transformationScope.transformations, + repoRoot = repoRoot, + logger = logger, + ).generate() + + logger.lifecycle("") + logger.lifecycle("------------------------------------------") + logger.lifecycle("Generation complete - {} file(s) written.", generated) + logger.lifecycle("") + logger.lifecycle("Next steps:") + logger.lifecycle(" 1. Add include(\"{}\") to settings.gradle.kts (if not present).", target.gradlePath) + logger.lifecycle(" 2. Register {} in the runtime NmsVersion enum.", target.name) + logger.lifecycle(" 3. Review the generated sources and fix remaining compilation errors.") + logger.lifecycle("------------------------------------------") + } + + // ------------------------------------------------------------------ // + + private fun confirmOverwriteIfNeeded(repoRoot: Path, target: NmsVersion) { + val targetSources = repoRoot + .resolve(target.modulePath) + .resolve("src/main/kotlin") + + if (!targetSources.exists()) return + + // Allow skipping the prompt via project property + if (project.hasProperty("forceOverwrite")) return + + val console = System.console() ?: throw GradleException( + "Target module ${target.name} already exists. " + + "Pass -PforceOverwrite to overwrite." + ) + + console.printf( + "%nTarget module '%s' already has sources at:%n %s%n", + target.name, + targetSources.toAbsolutePath(), + ) + val answer = console.readLine("Overwrite? [y/N] ")?.trim()?.lowercase() + + if (answer != "y" && answer != "yes") { + throw GradleException("Aborted by user.") + } + } +} + diff --git a/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/NmsGeneratorDsl.kt b/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/NmsGeneratorDsl.kt new file mode 100644 index 000000000..d67f75c6e --- /dev/null +++ b/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/NmsGeneratorDsl.kt @@ -0,0 +1,7 @@ +package dev.slne.surf.api.generator.nms + +/** Scope marker that prevents leaking receivers across nested DSL blocks. */ +@DslMarker +@Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE) +annotation class NmsGeneratorDsl + diff --git a/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/NmsGeneratorExtension.kt b/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/NmsGeneratorExtension.kt new file mode 100644 index 000000000..7fc8f3d47 --- /dev/null +++ b/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/NmsGeneratorExtension.kt @@ -0,0 +1,40 @@ +package dev.slne.surf.api.generator.nms + +/** + * Gradle extension for the `nms-module-generator` plugin. + * + * ```kotlin + * nmsGenerator { + * referenceVersion = NmsVersion.V26_1 + * targetVersion = NmsVersion.V1_21_11 + * + * transformations { + * renameClass("net.minecraft.resources.Identifier", + * "net.minecraft.resources.ResourceLocation") + * } + * } + * ``` + * + * @see GenerateNmsModulePlugin + */ +@NmsGeneratorDsl +open class NmsGeneratorExtension { + + /** The NMS version whose sources serve as the generation template. */ + lateinit var referenceVersion: NmsVersion + + /** The NMS version to generate. */ + lateinit var targetVersion: NmsVersion + + internal var transformationScope: TransformationScope = TransformationScope() + private set + + /** `true` if both [referenceVersion] and [targetVersion] have been set. */ + internal val isConfigured: Boolean + get() = ::referenceVersion.isInitialized && ::targetVersion.isInitialized + + /** Configures the source-code transformations applied during generation. */ + fun transformations(block: TransformationScope.() -> Unit) { + transformationScope = TransformationScope().apply(block) + } +} diff --git a/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/NmsModuleGenerator.kt b/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/NmsModuleGenerator.kt new file mode 100644 index 000000000..caf527e39 --- /dev/null +++ b/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/NmsModuleGenerator.kt @@ -0,0 +1,234 @@ +package dev.slne.surf.api.generator.nms + +import org.gradle.api.logging.Logger +import java.nio.file.Path +import kotlin.io.path.createDirectories +import kotlin.io.path.exists +import kotlin.io.path.writeText + +/** + * Copies every `.kt` source file from a [reference] NMS module into a + * [target] module, applying version-specific transformations along the way. + * + * Processing order per file: + * 1. Replace [reference] version-id and class-prefix with [target] equivalents. + * 2. Apply each [NmsTransformation] from [transformations] in declaration order. + * + * Additionally generates: + * - `META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider` for ServiceLoader + * - `build.gradle.kts` (only when absent) + */ +class NmsModuleGenerator( + private val reference: NmsVersion, + private val target: NmsVersion, + private val transformations: List, + private val repoRoot: Path, + private val logger: Logger, +) { + + private val referenceSourceRoot: Path = + repoRoot.resolve(reference.modulePath).resolve(KOTLIN_SOURCE_PATH) + + private val targetSourceRoot: Path = + repoRoot.resolve(target.modulePath).resolve(KOTLIN_SOURCE_PATH) + + // ------------------------------------------------------------------ // + // Public API // + // ------------------------------------------------------------------ // + + /** + * Runs the full generation pipeline and returns the number of + * generated source files. + */ + fun generate(): Int { + require(referenceSourceRoot.exists()) { + "Reference source root does not exist: $referenceSourceRoot" + } + + prepareTargetDirectory() + val generated = copyAndTransformSources() + generateServiceFile() + generateBuildFile() + + logger.lifecycle( + "Generated {} source file(s) in {}", + generated, + targetSourceRoot.toAbsolutePath(), + ) + return generated + } + + // ------------------------------------------------------------------ // + // Internal steps // + // ------------------------------------------------------------------ // + + private fun prepareTargetDirectory() { + if (targetSourceRoot.exists()) { + targetSourceRoot.toFile().deleteRecursively() + } + targetSourceRoot.createDirectories() + } + + private fun copyAndTransformSources(): Int { + val exclusions = transformations + .filterIsInstance() + .map(NmsTransformation.ExcludeFile::filePattern) + + val sourceFiles = referenceSourceRoot.toFile() + .walk() + .filter { it.isFile && it.extension == "kt" } + .toList() + + var count = 0 + for (file in sourceFiles) { + val relativeKey = referenceSourceRoot + .relativize(file.toPath()) + .toString() + .replace('\\', '/') + + if (exclusions.any { relativeKey.endsWith(it) || relativeKey == it }) { + logger.info("Excluded: {}", relativeKey) + continue + } + + val targetPath = targetSourceRoot.resolve(transformPath(relativeKey)) + targetPath.parent.createDirectories() + targetPath.writeText(transformContent(file.readText(), relativeKey)) + count++ + } + return count + } + + // ------------------------------------------------------------------ // + // Transformations // + // ------------------------------------------------------------------ // + + /** Rewrites directory segments and file names for the target version. */ + private fun transformPath(relativeKey: String): String = relativeKey + .replace(reference.versionId, target.versionId) + .replace(reference.classPrefix, target.classPrefix) + + /** Applies all transformations to a single file's content. */ + private fun transformContent(content: String, relativeKey: String): String { + // Always replace version-id and class-prefix first + var result = content + .replace(reference.versionId, target.versionId) + .replace(reference.classPrefix, target.classPrefix) + + for (t in transformations) { + result = apply(result, t, relativeKey) + } + return result + } + + private fun apply( + content: String, + transformation: NmsTransformation, + relativeKey: String, + ): String = when (transformation) { + + is NmsTransformation.RenameClass -> { + var result = content.replace( + "import ${transformation.oldFqn}", + "import ${transformation.newFqn}", + ) + if (transformation.oldSimpleName != transformation.newSimpleName) { + result = result.replace( + Regex("\\b${Regex.escape(transformation.oldSimpleName)}\\b"), + transformation.newSimpleName, + ) + } + result + } + + is NmsTransformation.RemoveImport -> + content + .replace("import ${transformation.fqn}\n", "") + .replace("import ${transformation.fqn}\r\n", "") + + is NmsTransformation.ReplaceCode -> + content.replace(transformation.old, transformation.new) + + is NmsTransformation.ReplacePattern -> + content.replace(transformation.pattern, transformation.replacement) + + is NmsTransformation.TransformFile -> + if (relativeKey.endsWith(transformation.filePattern) || relativeKey == transformation.filePattern) { + transformation.transformer(content) + } else { + content + } + + is NmsTransformation.ExcludeFile -> + content // already handled at file level + } + + // ------------------------------------------------------------------ // + // Scaffold generation // + // ------------------------------------------------------------------ // + + private fun generateServiceFile() { + val serviceDir = repoRoot + .resolve(target.modulePath) + .resolve("src/main/resources/META-INF/services") + serviceDir.createDirectories() + + val providerFqn = "$PROVIDER_PACKAGE_PREFIX${target.versionId}.${target.classPrefix}NmsProvider" + serviceDir.resolve(NMS_PROVIDER_SERVICE).writeText("$providerFqn\n") + + logger.lifecycle("Generated service file: {}", providerFqn) + } + + private fun generateBuildFile() { + val buildFile = repoRoot.resolve(target.modulePath).resolve("build.gradle.kts") + if (buildFile.exists()) { + logger.lifecycle("build.gradle.kts already exists, skipping") + return + } + + buildFile.parent.createDirectories() + buildFile.writeText(buildGradleTemplate()) + logger.lifecycle("Generated build.gradle.kts (paperDevBundle={})", target.paperDevBundle) + } + + private fun buildGradleTemplate(): String = """ + |plugins { + | `core-convention` + | id("io.papermc.paperweight.userdev") apply true + |} + | + |kotlin { + | compilerOptions { + | optIn.add("dev.slne.surf.api.paper.visualizer.visualizer.ExperimentalVisualizerApi") + | } + |} + | + |dependencies { + | api(projects.surfApiPaper.surfApiPaperNms.surfApiPaperNmsCommon) + | api(projects.surfApiCore.surfApiCoreServer) + | + | paperweight.paperDevBundle("${target.paperDevBundle}") + | + | compileOnly(libs.placeholder.api) + | compileOnly(libs.reflection.remapper) + | compileOnly(libs.mccoroutine.folia.api) + | compileOnly(libs.scoreboard.library.api) + | + | implementation(libs.bytebuddy) + |} + | + |configurations.all { + | exclude(group = "org.spigotmc", module = "spigot-api") + |} + """.trimMargin() + "\n" + + private companion object { + const val KOTLIN_SOURCE_PATH = "src/main/kotlin" + const val PROVIDER_PACKAGE_PREFIX = "dev.slne.surf.api.paper.server.nms." + const val NMS_PROVIDER_SERVICE = "dev.slne.surf.api.paper.nms.common.NmsProvider" + } +} + + + + diff --git a/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/NmsTransformation.kt b/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/NmsTransformation.kt new file mode 100644 index 000000000..a14582761 --- /dev/null +++ b/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/NmsTransformation.kt @@ -0,0 +1,70 @@ +package dev.slne.surf.api.generator.nms + +/** + * A single source-code transformation applied during NMS module generation. + * + * Transformations run **after** the automatic version-id and class-prefix + * replacements and are applied in declaration order. + */ +sealed class NmsTransformation { + + /** + * Renames a fully-qualified class in every generated file. + * + * Handles both `import` statements and in-code simple-name references + * (via `\b` word-boundary matching when the simple names differ). + * + * @property oldFqn Fully-qualified name of the class in the reference module. + * @property newFqn Fully-qualified name of the replacement class. + */ + data class RenameClass( + val oldFqn: String, + val newFqn: String, + ) : NmsTransformation() { + val oldSimpleName: String get() = oldFqn.substringAfterLast('.') + val newSimpleName: String get() = newFqn.substringAfterLast('.') + } + + /** + * Removes an `import` line from every generated file. + * + * @property fqn Fully-qualified name to remove (without the `import` keyword). + */ + data class RemoveImport(val fqn: String) : NmsTransformation() + + /** + * Literal string replacement applied to every generated file. + * + * @property old Text to search for. + * @property new Replacement text. + */ + data class ReplaceCode(val old: String, val new: String) : NmsTransformation() + + /** + * Regex-based replacement applied to every generated file. + * + * @property pattern Compiled regex pattern. + * @property replacement Replacement string (supports group references like `$1`). + */ + data class ReplacePattern(val pattern: Regex, val replacement: String) : NmsTransformation() + + /** + * Custom transformation function targeting files whose relative path + * matches or ends with [filePattern]. + * + * @property filePattern Relative path suffix to match (e.g. `"bridges/SomeFile.kt"`). + * @property transformer Receives the current file content and returns the transformed content. + */ + data class TransformFile( + val filePattern: String, + val transformer: (String) -> String, + ) : NmsTransformation() + + /** + * Excludes matching files from generation entirely. + * + * @property filePattern Relative path suffix to match. + */ + data class ExcludeFile(val filePattern: String) : NmsTransformation() +} + diff --git a/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/NmsVersion.kt b/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/NmsVersion.kt new file mode 100644 index 000000000..1c06f6b9a --- /dev/null +++ b/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/NmsVersion.kt @@ -0,0 +1,42 @@ +package dev.slne.surf.api.generator.nms + +/** + * Supported NMS versions for module generation. + * + * Each entry encapsulates all version-specific metadata required by the + * generator, so consumers only need to reference an enum constant instead + * of specifying identifiers, prefixes, and bundle versions manually. + * + * @property versionId Identifier used in package names and directory paths (e.g. `"v26_1"`). + * @property classPrefix Prefix applied to generated class names (e.g. `"V26_1"`). + * @property paperDevBundle Version string passed to `paperweight.paperDevBundle(…)`. + */ +enum class NmsVersion( + val versionId: String, + val classPrefix: String, + val paperDevBundle: String, +) { + V1_21_11( + versionId = "v1_21_11", + classPrefix = "V1_21_11", + paperDevBundle = "1.21.11-R0.1-SNAPSHOT", + ), + V26_1( + versionId = "v26_1", + classPrefix = "V26_1", + paperDevBundle = "26.1+", + ); + + /** Relative path from the repository root to this version's Gradle module. */ + val modulePath: String + get() = "$MODULE_BASE_PATH${versionId.replace('_', '-')}" + + /** Gradle project path usable in `settings.gradle.kts` `include(…)` calls. */ + val gradlePath: String + get() = ":${modulePath.replace('/', ':')}" + + private companion object { + const val MODULE_BASE_PATH = "surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-" + } +} + diff --git a/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/TransformationScope.kt b/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/TransformationScope.kt new file mode 100644 index 000000000..05b5e3a1c --- /dev/null +++ b/surf-api-generator/gradle-nms-module-generator/src/main/kotlin/dev/slne/surf/api/generator/nms/TransformationScope.kt @@ -0,0 +1,56 @@ +package dev.slne.surf.api.generator.nms + +/** + * DSL scope for declaring [NmsTransformation] rules. + * + * Available inside the `transformations { … }` block of the + * [NmsGeneratorExtension]. Each method adds a transformation that will + * be applied in declaration order during generation. + */ +@NmsGeneratorDsl +class TransformationScope internal constructor() { + + private val _transformations = mutableListOf() + + /** Snapshot of all registered transformations. */ + internal val transformations: List get() = _transformations.toList() + + /** + * Renames a fully-qualified class in all generated files. + * + * Automatically rewrites the `import` line **and** every in-code + * reference (via word-boundary matching when the simple names differ). + */ + fun renameClass(oldFqn: String, newFqn: String) { + _transformations += NmsTransformation.RenameClass(oldFqn, newFqn) + } + + /** Removes the `import` line for [fqn] from all generated files. */ + fun removeImport(fqn: String) { + _transformations += NmsTransformation.RemoveImport(fqn) + } + + /** Replaces every occurrence of [old] with [new] in all generated files. */ + fun replaceCode(old: String, new: String) { + _transformations += NmsTransformation.ReplaceCode(old, new) + } + + /** Replaces matches of the given regex [pattern] with [replacement]. */ + fun replacePattern(pattern: String, replacement: String) { + _transformations += NmsTransformation.ReplacePattern(Regex(pattern), replacement) + } + + /** + * Applies [transformer] to every file whose relative path ends with + * [filePattern] (uses `/` as separator). + */ + fun transformFile(filePattern: String, transformer: (String) -> String) { + _transformations += NmsTransformation.TransformFile(filePattern, transformer) + } + + /** Excludes files whose relative path ends with [filePattern] from generation. */ + fun excludeFile(filePattern: String) { + _transformations += NmsTransformation.ExcludeFile(filePattern) + } +} + diff --git a/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsGeneratorMain.kt b/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsGeneratorMain.kt deleted file mode 100644 index dc9019d81..000000000 --- a/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsGeneratorMain.kt +++ /dev/null @@ -1,30 +0,0 @@ -package dev.slne.surf.api.gen.nms - -import java.nio.file.Path -import kotlin.io.path.Path - -/** - * Entry point for NMS version-specific code generation. - * - * Usage: Run with repo root as the first argument. - * From Gradle: `./gradlew :surf-api-generator:generateNms` - */ -fun main(args: Array) { - val repoRoot = if (args.isNotEmpty()) Path(args[0]) else Path("..") - - println("Generating NMS version-specific code from reference ${NmsVersionConfigs.REFERENCE_VERSION_ID}...") - - val referenceSourceRoot = repoRoot - .resolve(NmsVersionConfigs.REFERENCE_MODULE_PATH) - .resolve("src/main/kotlin") - - val generator = NmsTemplateGenerator( - referenceVersionId = NmsVersionConfigs.REFERENCE_VERSION_ID, - referenceClassPrefix = NmsVersionConfigs.REFERENCE_CLASS_PREFIX, - referenceSourceRoot = referenceSourceRoot, - targets = NmsVersionConfigs.ALL_TARGETS, - ) - - val totalGenerated = generator.generate(repoRoot) - println("NMS generation complete: $totalGenerated files generated across ${NmsVersionConfigs.ALL_TARGETS.size} target(s)") -} diff --git a/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsTemplateGenerator.kt b/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsTemplateGenerator.kt deleted file mode 100644 index c84362723..000000000 --- a/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsTemplateGenerator.kt +++ /dev/null @@ -1,152 +0,0 @@ -package dev.slne.surf.api.gen.nms - -import java.nio.file.Path -import kotlin.io.path.* - -/** - * Generates version-specific NMS module source code from a reference module. - * - * The reference module (e.g. v26-1) serves as the canonical "template". - * This generator copies every source file, applying version-specific - * transformations: - * - * 1. Package name replacement (reference version → target version) - * 2. Class prefix replacement (e.g. V26_1 → V1_21_11) - * 3. Import replacements for changed NMS APIs - * 4. Code-level replacements for renamed methods/classes - * 5. Per-file custom transformers for structural differences - */ -class NmsTemplateGenerator( - private val referenceVersionId: String, - private val referenceClassPrefix: String, - private val referenceSourceRoot: Path, - private val targets: List, -) { - - /** - * Generate all target modules from the reference source files. - * - * @param repoRoot absolute path to the repository root - * @return number of files generated across all targets - */ - fun generate(repoRoot: Path): Int { - require(referenceSourceRoot.exists()) { - "Reference source root does not exist: $referenceSourceRoot" - } - - var totalGenerated = 0 - - for (target in targets) { - totalGenerated += generateTarget(repoRoot, target) - } - - return totalGenerated - } - - private fun generateTarget(repoRoot: Path, target: NmsVersionConfig): Int { - val targetSourceRoot = repoRoot.resolve(target.sourceModulePath) - .resolve("src/main/kotlin") - - // Clean existing generated sources - if (targetSourceRoot.exists()) { - targetSourceRoot.toFile().deleteRecursively() - } - targetSourceRoot.createDirectories() - - val sourceFiles = referenceSourceRoot.toFile() - .walk() - .filter { it.isFile && it.extension == "kt" } - .toList() - - var generated = 0 - - for (sourceFile in sourceFiles) { - val relativePath = referenceSourceRoot.relativize(sourceFile.toPath()) - val transformedRelativePath = transformPath(relativePath, target) - val targetFile = targetSourceRoot.resolve(transformedRelativePath) - targetFile.parent.createDirectories() - - val originalContent = sourceFile.readText() - val relativeKey = relativePath.toString().replace('\\', '/') - val transformedContent = transformContent(originalContent, target, relativeKey) - - targetFile.writeText(transformedContent) - generated++ - } - - // Generate META-INF/services file for ServiceLoader registration - generateServiceFile(repoRoot, target) - - println("Generated $generated files for ${target.versionId} in ${targetSourceRoot.toAbsolutePath()}") - return generated - } - - /** - * Generates the META-INF/services file for ServiceLoader registration. - * This ensures the NmsProvider implementation is discoverable at runtime, - * regardless of whether KSP annotation processing runs successfully. - */ - private fun generateServiceFile(repoRoot: Path, target: NmsVersionConfig) { - val serviceDir = repoRoot.resolve(target.sourceModulePath) - .resolve("src/main/resources/META-INF/services") - serviceDir.createDirectories() - - // Derive the provider class name from the reference module's NmsProvider - val referenceProviderPackage = "dev.slne.surf.api.paper.server.nms.$referenceVersionId" - val referenceProviderClass = "${referenceClassPrefix}NmsProvider" - val targetProviderPackage = "dev.slne.surf.api.paper.server.nms.${target.versionId}" - val targetProviderClass = "${target.classPrefix}NmsProvider" - - val serviceFile = serviceDir.resolve("dev.slne.surf.api.paper.nms.common.NmsProvider") - serviceFile.writeText("$targetProviderPackage.$targetProviderClass\n") - - println("Generated service file for ${target.versionId}: $targetProviderPackage.$targetProviderClass") - } - - /** - * Transforms a relative path from the reference module to the target module. - * Replaces the reference package directory segments with target ones. - */ - private fun transformPath(relativePath: Path, target: NmsVersionConfig): Path { - val pathStr = relativePath.toString().replace('\\', '/') - val transformed = pathStr - .replace(referenceVersionId, target.versionId) - .replace(referenceClassPrefix, target.classPrefix) - return Path(transformed) - } - - /** - * Transforms file content from reference version to target version. - */ - private fun transformContent( - content: String, - target: NmsVersionConfig, - relativeKey: String, - ): String { - var result = content - - // 1. Replace package names (reference version → target version) - result = result.replace(referenceVersionId, target.versionId) - - // 2. Replace class prefixes (e.g. V26_1 → V1_21_11) - result = result.replace(referenceClassPrefix, target.classPrefix) - - // 3. Apply import-level replacements - for ((old, new) in target.importReplacements) { - result = result.replace(old, new) - } - - // 4. Apply code-level replacements - for ((old, new) in target.codeReplacements) { - result = result.replace(old, new) - } - - // 5. Apply per-file custom transformers - val transformer = target.fileTransformers[relativeKey] - if (transformer != null) { - result = transformer(result) - } - - return result - } -} diff --git a/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsVersionConfig.kt b/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsVersionConfig.kt deleted file mode 100644 index 9c7649df3..000000000 --- a/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsVersionConfig.kt +++ /dev/null @@ -1,20 +0,0 @@ -package dev.slne.surf.api.gen.nms - -/** - * Configuration for a target NMS version. - * - * @property versionId Short identifier used in package/class names, e.g. "v1_21_11" - * @property classPrefix Prefix for generated class names, e.g. "V1_21_11" - * @property sourceModulePath Relative path from repo root to the target module's source root - * @property importReplacements Map of import replacements (old → new) applied to every file - * @property codeReplacements Map of code-level string replacements applied after import replacement - * @property fileTransformers Per-file transformers keyed by relative source path (from the reference module) - */ -data class NmsVersionConfig( - val versionId: String, - val classPrefix: String, - val sourceModulePath: String, - val importReplacements: Map = emptyMap(), - val codeReplacements: Map = emptyMap(), - val fileTransformers: Map String> = emptyMap(), -) diff --git a/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsVersionConfigs.kt b/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsVersionConfigs.kt deleted file mode 100644 index 746c4225d..000000000 --- a/surf-api-generator/src/main/kotlin/dev/slne/surf/api/gen/nms/NmsVersionConfigs.kt +++ /dev/null @@ -1,58 +0,0 @@ -package dev.slne.surf.api.gen.nms - -/** - * Registry of all NMS version configurations. - * - * The **reference version** is v26_1 (Paper 26.1+). All other versions are - * generated by transforming the reference sources. - * - * To add a new Minecraft version: - * 1. Add an [NmsVersionConfig] entry here - * 2. Create the Gradle module (build.gradle.kts with correct paperweight dev-bundle) - * 3. Register the module in settings.gradle.kts - * 4. Re-run the generator: `./gradlew :surf-api-generator:generateNms` - */ -object NmsVersionConfigs { - - /** Reference version identifiers (source of truth). */ - const val REFERENCE_VERSION_ID = "v26_1" - const val REFERENCE_CLASS_PREFIX = "V26_1" - const val REFERENCE_MODULE_PATH = "surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1" - - /** - * NMS version config for Minecraft 1.21.11 (Canvas). - * - * Key differences from 26.1: - * - `net.minecraft.resources.Identifier` → `net.minecraft.resources.ResourceLocation` - * - `Identifier.fromNamespaceAndPath(...)` → `ResourceLocation.fromNamespaceAndPath(...)` - * - `ClientboundClearDialogPacket` does not exist → clearDialogs becomes a no-op - * - `player.showDialog(...)` does not exist → removed - * - `noticeDialogWithBuilder` import does not exist → removed - * - `TypedEntityData` does not exist → use `CustomData.of(...)` instead - */ - val V1_21_11 = NmsVersionConfig( - versionId = "v1_21_11", - classPrefix = "V1_21_11", - sourceModulePath = "surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11", - importReplacements = mapOf( - "import net.minecraft.resources.Identifier" to "import net.minecraft.resources.ResourceLocation", - "import net.minecraft.world.item.component.TypedEntityData\n" to "", - ), - codeReplacements = mapOf( - // Identifier class → ResourceLocation - "Identifier.fromNamespaceAndPath(" to "ResourceLocation.fromNamespaceAndPath(", - // Type references in function signatures - "id: Identifier" to "id: ResourceLocation", - "(id: Identifier," to "(id: ResourceLocation,", - "fun showPacket(id: Identifier," to "fun showPacket(id: ResourceLocation,", - "fun hidePacket(id: Identifier)" to "fun hidePacket(id: ResourceLocation)", - "fun createAdvancement(id: Identifier," to "fun createAdvancement(id: ResourceLocation,", - // TypedEntityData → CustomData.of - "TypedEntityData.decodeEntity(nbt)" to "CustomData.of(nbt)", - ), - fileTransformers = mapOf(), - ) - - /** All target versions that should be generated from the reference. */ - val ALL_TARGETS = listOf(V1_21_11) -} From 36baa5968e8efa12854d685804b908d8e1b6a1a2 Mon Sep 17 00:00:00 2001 From: twisti <76837088+twisti-dev@users.noreply.github.com> Date: Wed, 15 Apr 2026 16:46:11 +0200 Subject: [PATCH 19/34] =?UTF-8?q?=E2=9C=A8=20feat(nms):=20unify=20BlockGlo?= =?UTF-8?q?wingData=20class=20for=20multiple=20NMS=20versions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - rename V1_21_11BlockGlowingData and V26_1BlockGlowingData to BlockGlowingData - update references to use the unified BlockGlowingData class - change BlockPlayerData to use ConcurrentHashMap for blocks - refactor NmsProvider to support multiple NMS versions --- build.gradle.kts | 9 ++-- settings.gradle.kts | 2 +- .../surf/api/paper/nms/common/NmsProvider.kt | 23 +++++++--- .../nms/v1_21_11/V1_21_11NmsProvider.kt | 24 ++-------- .../bridges/V1_21_11SurfPaperNmsBridgeImpl.kt | 9 ++-- .../V1_21_11SurfPaperNmsGlowingBridgeImpl.kt | 7 +-- .../glow/V1_21_11GlowingLifecycleHandler.kt | 2 + .../glow/V1_21_11SurfGlowingApiImpl.kt | 44 +++++++++---------- ...lockGlowingData.kt => BlockGlowingData.kt} | 11 +++-- .../v1_21_11/glow/block/BlockPlayerData.kt | 4 +- .../v1_21_11/glow/entity/EntityGlowingData.kt | 9 ++-- .../v1_21_11/glow/entity/EntityPlayerData.kt | 2 + .../packets/V1_21_11PacketRegistry.kt | 10 ++--- .../listener/V1_21_11GlowingPacketListener.kt | 2 +- .../server/nms/v26_1/V26_1NmsProvider.kt | 32 +++++--------- .../bridges/V26_1SurfPaperNmsBridgeImpl.kt | 9 ++-- .../V26_1SurfPaperNmsGlowingBridgeImpl.kt | 7 +-- .../V26_1SurfPaperNmsItemBridgeImpl.kt | 5 ++- .../bridges/V26_1SurfPaperNmsNbtBridgeImpl.kt | 1 - .../glow/V26_1GlowingLifecycleHandler.kt | 2 + .../nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt | 44 +++++++++---------- ...lockGlowingData.kt => BlockGlowingData.kt} | 11 +++-- .../nms/v26_1/glow/block/BlockPlayerData.kt | 4 +- .../v26_1/glow/entity/EntityGlowingData.kt | 9 ++-- .../nms/v26_1/glow/entity/EntityPlayerData.kt | 2 + .../listener/packets/V26_1PacketRegistry.kt | 10 ++--- .../listener/V26_1GlowingPacketListener.kt | 2 +- .../nms/v26_1/reflection/V26_1ItemProxy.kt | 12 +++++ .../nms/v26_1/reflection/V26_1Reflection.kt | 6 ++- ...slne.surf.api.paper.nms.common.NmsProvider | 1 + 30 files changed, 152 insertions(+), 163 deletions(-) rename surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/block/{V1_21_11BlockGlowingData.kt => BlockGlowingData.kt} (90%) rename surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/{V26_1BlockGlowingData.kt => BlockGlowingData.kt} (90%) create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ItemProxy.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider diff --git a/build.gradle.kts b/build.gradle.kts index 07fd07fb0..5649faae2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,4 @@ +import dev.slne.surf.api.generator.nms.NmsVersion import org.jetbrains.kotlin.gradle.dsl.KotlinJvmExtension plugins { @@ -5,10 +6,10 @@ plugins { id("dev.slne.surf.api.generator.nms-module-generator") } -//nmsGenerator { -// referenceVersion = NmsVersion.V26_1 -// targetVersion = NmsVersion.V1_21_11 -//} +nmsGenerator { + referenceVersion = NmsVersion.V1_21_11 + targetVersion = NmsVersion.V26_1 +} allprojects { diff --git a/settings.gradle.kts b/settings.gradle.kts index 9c688c3a4..cca86ba88 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -19,8 +19,8 @@ include(":surf-api-core:surf-api-core-server") include(":surf-api-paper:surf-api-paper") include(":surf-api-paper:surf-api-paper-nms:surf-api-paper-nms-common") -include(":surf-api-paper:surf-api-paper-nms:surf-api-paper-nms-v26-1") include(":surf-api-paper:surf-api-paper-nms:surf-api-paper-nms-v1-21-11") +include(":surf-api-paper:surf-api-paper-nms:surf-api-paper-nms-v26-1") include(":surf-api-paper:surf-api-paper-server") include(":surf-api-velocity:surf-api-velocity") diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt index 5f339e846..5c875a8c7 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt @@ -1,6 +1,8 @@ package dev.slne.surf.api.paper.nms.common +import dev.slne.surf.api.core.util.logger import dev.slne.surf.api.paper.glow.SurfGlowingApi +import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge import dev.slne.surf.api.paper.nms.bridges.* import dev.slne.surf.api.paper.nms.bridges.packets.SurfPaperNmsPacketBridges @@ -21,6 +23,7 @@ import java.util.* * * Implementations are discovered at runtime using [java.util.ServiceLoader]. */ +@NmsUseWithCaution interface NmsProvider { /** * The NMS version this provider supports. @@ -90,7 +93,7 @@ interface NmsProvider { fun shutdown() companion object { - private val log = dev.slne.surf.api.core.util.logger() + private val log = logger() /** * Loads the [NmsProvider] for the currently running Minecraft version. @@ -99,11 +102,19 @@ interface NmsProvider { */ val current: NmsProvider by lazy { val version = NmsVersion.current - val providers = ServiceLoader.load( - NmsProvider::class.java, - NmsProvider::class.java.classLoader - ) - .toList() // TODO: Bug: Finds only a single provider, even if multiple are present. The Provider which is declared as a dependency first is found. + val loader = ServiceLoader.load(NmsProvider::class.java) + val providers = mutableListOf() + + val iterator = loader.iterator() + while (iterator.hasNext()) { + val instance: NmsProvider? + try { + instance = iterator.next() + } catch (_: ServiceConfigurationError) { + continue + } + providers.add(instance) + } log.atInfo().log("Looking for NmsProvider with version: %s", version) log.atInfo().log( diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt index 01e81f9a2..a045b679c 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt @@ -2,6 +2,7 @@ package dev.slne.surf.api.paper.server.nms.v1_21_11 import com.google.auto.service.AutoService import dev.slne.surf.api.paper.glow.SurfGlowingApi +import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge import dev.slne.surf.api.paper.nms.bridges.* import dev.slne.surf.api.paper.nms.bridges.packets.SurfPaperNmsPacketBridges @@ -27,15 +28,12 @@ import dev.slne.surf.api.paper.server.nms.v1_21_11.packet.lore.V1_21_11PacketLor import dev.slne.surf.api.paper.server.nms.v1_21_11.packet.lore.V1_21_11PacketLoreRegistry import dev.slne.surf.api.paper.server.nms.v1_21_11.reflection.V1_21_11Reflection import dev.slne.surf.api.paper.server.nms.v1_21_11.region.V1_21_11TickThreadGuard -import org.bukkit.plugin.java.JavaPlugin +@OptIn(NmsUseWithCaution::class) @AutoService(NmsProvider::class) class V1_21_11NmsProvider : NmsProvider { override val version: NmsVersion = NmsVersion.V1_21_11 - private var glowingBridge: V1_21_11SurfPaperNmsGlowingBridgeImpl? = null - private var glowingApi: V1_21_11SurfGlowingApiImpl? = null - override fun createNmsBridge(): SurfPaperNmsBridge = V1_21_11SurfPaperNmsBridgeImpl() override fun createCommonBridge(): SurfPaperNmsCommonBridge = V1_21_11SurfPaperNmsCommonBridgeImpl() @@ -45,12 +43,7 @@ class V1_21_11NmsProvider : NmsProvider { override fun createItemBridge(): SurfPaperNmsItemBridge = V1_21_11SurfPaperNmsItemBridgeImpl() override fun createNbtBridge(): SurfPaperNmsNbtBridge = V1_21_11SurfPaperNmsNbtBridgeImpl() - override fun createGlowingBridge(): SurfPaperNmsGlowingBridge { - return glowingBridge ?: V1_21_11SurfPaperNmsGlowingBridgeImpl().also { - glowingBridge = it - V1_21_11SurfPaperNmsGlowingBridgeImpl.INSTANCE = it - } - } + override fun createGlowingBridge(): SurfPaperNmsGlowingBridge = V1_21_11SurfPaperNmsGlowingBridgeImpl override fun createStatsBridge(): SurfPaperNmsStatsBridge = V1_21_11SurfPaperNmsStatsBridgeImpl() @@ -87,16 +80,7 @@ class V1_21_11NmsProvider : NmsProvider { override fun createGlowingLifecycleHandler(): GlowingLifecycleHandler = V1_21_11GlowingLifecycleHandler() - override fun createGlowingApi(): SurfGlowingApi { - // Ensure glowing bridge is initialized before the API uses it - createGlowingBridge() - - val plugin = JavaPlugin.getProvidingPlugin(V1_21_11NmsProvider::class.java) as JavaPlugin - val api = V1_21_11SurfGlowingApiImpl(plugin) - V1_21_11SurfGlowingApiImpl.INSTANCE = api - glowingApi = api - return api - } + override fun createGlowingApi(): SurfGlowingApi = V1_21_11SurfGlowingApiImpl override fun createPacketListeners(): List = listOf( V1_21_11PacketLoreListener, diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsBridgeImpl.kt index e62fb4bd4..7798c93a3 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsBridgeImpl.kt @@ -9,19 +9,18 @@ import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge import dev.slne.surf.api.paper.nms.listener.packets.clientbound.NmsClientboundPacket import dev.slne.surf.api.paper.nms.listener.packets.serverbound.NmsServerboundPacket import dev.slne.surf.api.paper.packet.listener.listener.PacketListenerResult -import dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.V1_21_11NmsPacketImpl import org.bukkit.entity.Player import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.CopyOnWriteArraySet @NmsUseWithCaution class V1_21_11SurfPaperNmsBridgeImpl : SurfPaperNmsBridge { + private typealias PacketListenerMap = ConcurrentHashMap, CopyOnWriteArraySet> + private val log = logger() - private val serverboundPacketListeners = - ConcurrentHashMap, CopyOnWriteArraySet>>() - private val clientboundPacketListeners = - ConcurrentHashMap, CopyOnWriteArraySet>>() + private val serverboundPacketListeners = PacketListenerMap>() + private val clientboundPacketListeners = PacketListenerMap>() override fun registerServerboundPacketListener(listener: NmsServerboundPacketListener<*>) { val packetClass = listener.packetClass diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsGlowingBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsGlowingBridgeImpl.kt index 1a8849ad3..b8af4a206 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsGlowingBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsGlowingBridgeImpl.kt @@ -14,7 +14,7 @@ import net.minecraft.network.syncher.SynchedEntityData.DataValue import org.bukkit.entity.Entity @NmsUseWithCaution -class V1_21_11SurfPaperNmsGlowingBridgeImpl : SurfPaperNmsGlowingBridge { +object V1_21_11SurfPaperNmsGlowingBridgeImpl : SurfPaperNmsGlowingBridge { fun createTeam(data: V1_21_11TeamData): PacketOperation = V1_21_11PacketOperationImpl.simple { ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(data.team, true) @@ -53,9 +53,4 @@ class V1_21_11SurfPaperNmsGlowingBridgeImpl : SurfPaperNmsGlowingBridge { val dataAccessor = V1_21_11Reflection.ENTITY_PROXY.getDataFlagsSharedId() return entity.toNms().entityData.get(dataAccessor) } - - companion object { - lateinit var INSTANCE: V1_21_11SurfPaperNmsGlowingBridgeImpl - internal set - } } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11GlowingLifecycleHandler.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11GlowingLifecycleHandler.kt index 29a5b9456..a6d96d25b 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11GlowingLifecycleHandler.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11GlowingLifecycleHandler.kt @@ -1,5 +1,6 @@ package dev.slne.surf.api.paper.server.nms.v1_21_11.glow +import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation import dev.slne.surf.api.paper.nms.common.GlowingLifecycleHandler import dev.slne.surf.api.paper.util.chunkX @@ -7,6 +8,7 @@ import dev.slne.surf.api.paper.util.chunkZ import org.bukkit.World import org.bukkit.entity.Player +@NmsUseWithCaution class V1_21_11GlowingLifecycleHandler : GlowingLifecycleHandler { override fun removeAllGlowingOnQuit(player: Player) { V1_21_11SurfGlowingApiImpl.removeAllGlowingOnQuit(player) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11SurfGlowingApiImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11SurfGlowingApiImpl.kt index fb0c89154..a026f8b9b 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11SurfGlowingApiImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11SurfGlowingApiImpl.kt @@ -7,7 +7,7 @@ import dev.slne.surf.api.paper.glow.SurfGlowingApi import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.V1_21_11SurfPaperNmsGlowingBridgeImpl -import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.block.V1_21_11BlockGlowingData +import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.block.BlockGlowingData import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.block.BlockPlayerData import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.entity.EntityGlowingData import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.entity.EntityPlayerData @@ -24,7 +24,11 @@ import java.util.* import java.util.concurrent.ConcurrentHashMap @NmsUseWithCaution -class V1_21_11SurfGlowingApiImpl(private val plugin: JavaPlugin) : SurfGlowingApi { +object V1_21_11SurfGlowingApiImpl : SurfGlowingApi { + private val entityPlayerData = ConcurrentHashMap() + private val blockPlayerData = ConcurrentHashMap() + + val glowingFlag = 1 shl V1_21_11Reflection.ENTITY_PROXY.getFlagGlowing() override fun makeGlowing( target: Entity, @@ -36,7 +40,7 @@ class V1_21_11SurfGlowingApiImpl(private val plugin: JavaPlugin) : SurfGlowingAp teamIdFor(target), viewer, color, - V1_21_11SurfPaperNmsGlowingBridgeImpl.INSTANCE.getCurrentFlags(target) + V1_21_11SurfPaperNmsGlowingBridgeImpl.getCurrentFlags(target) ) } @@ -50,7 +54,7 @@ class V1_21_11SurfGlowingApiImpl(private val plugin: JavaPlugin) : SurfGlowingAp val nmsColor = color?.let { PaperAdventure.asVanilla(it) } val uuid = viewer.uniqueId val playerData = entityPlayerData.computeIfAbsent(uuid) { EntityPlayerData(uuid) } - val glowingData = playerData.entities.get(targetId) + val glowingData = playerData.entities[targetId] val operation = PacketOperation.start() if (glowingData == null) { @@ -61,7 +65,7 @@ class V1_21_11SurfGlowingApiImpl(private val plugin: JavaPlugin) : SurfGlowingAp nmsColor, otherFlags ) - playerData.entities.put(targetId, newData) + playerData.entities[targetId] = newData operation.add(newData.sendGlowingFlag(enabled = true, ignorePacket = true)) if (nmsColor != null) { @@ -95,9 +99,10 @@ class V1_21_11SurfGlowingApiImpl(private val plugin: JavaPlugin) : SurfGlowingAp val blockData = playerData.blocks[blockLocation] if (blockData == null) { - val newData = V1_21_11BlockGlowingData(playerData, blockLocation, color) + val newData = BlockGlowingData(playerData, blockLocation, color) playerData.blocks[blockLocation] = newData + val plugin = JavaPlugin.getProvidingPlugin(javaClass) plugin.launch(plugin.entityDispatcher(viewer)) { if (viewer.isChunkVisible(blockLocation)) { newData.spawn().execute(viewer) @@ -148,26 +153,17 @@ class V1_21_11SurfGlowingApiImpl(private val plugin: JavaPlugin) : SurfGlowingAp private fun teamIdFor(entity: Entity) = (entity as? Player)?.name ?: entity.uniqueId.toString() - companion object { - lateinit var INSTANCE: V1_21_11SurfGlowingApiImpl - internal set - - private val entityPlayerData = ConcurrentHashMap() - private val blockPlayerData = ConcurrentHashMap() - val glowingFlag = 1 shl V1_21_11Reflection.ENTITY_PROXY.getFlagGlowing() + fun getEntityPlayerData(player: Player): EntityPlayerData? = + entityPlayerData[player.uniqueId] - fun getEntityPlayerData(player: Player): EntityPlayerData? = - entityPlayerData[player.uniqueId] + fun getBlockPlayerData(player: Player): BlockPlayerData? = + blockPlayerData[player.uniqueId] - fun getBlockPlayerData(player: Player): BlockPlayerData? = - blockPlayerData[player.uniqueId] - - fun removeAllGlowingOnQuit(player: Player) { - val uuid = player.uniqueId - V1_21_11TeamData.removeFromAll(uuid) - entityPlayerData.remove(uuid)?.entities?.clear() - blockPlayerData.remove(uuid)?.blocks?.clear() - } + fun removeAllGlowingOnQuit(player: Player) { + val uuid = player.uniqueId + V1_21_11TeamData.removeFromAll(uuid) + entityPlayerData.remove(uuid)?.entities?.clear() + blockPlayerData.remove(uuid)?.blocks?.clear() } } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/block/V1_21_11BlockGlowingData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/block/BlockGlowingData.kt similarity index 90% rename from surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/block/V1_21_11BlockGlowingData.kt rename to surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/block/BlockGlowingData.kt index 60625ee89..04fa1ec90 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/block/V1_21_11BlockGlowingData.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/block/BlockGlowingData.kt @@ -17,7 +17,7 @@ import org.bukkit.Location import java.util.* @OptIn(NmsUseWithCaution::class) -class V1_21_11BlockGlowingData( +class BlockGlowingData( val playerData: BlockPlayerData, val location: Location, var color: NamedTextColor, @@ -45,16 +45,15 @@ class V1_21_11BlockGlowingData( 0.0 ) } - val invisibleOperation = V1_21_11SurfPaperNmsGlowingBridgeImpl.INSTANCE - .setEntityFlags(entityId, invisibleFlag) - + val invisibleOperation = V1_21_11SurfPaperNmsGlowingBridgeImpl.setEntityFlags(entityId, invisibleFlag) + return spawnOperation + invisibleOperation } fun updateColor() { val player = playerData.player ?: return - V1_21_11SurfGlowingApiImpl.INSTANCE.makeGlowing( + V1_21_11SurfGlowingApiImpl.makeGlowing( entityId, uuid.toString(), player, @@ -65,7 +64,7 @@ class V1_21_11BlockGlowingData( fun remove() { playerData.player?.let { SurfPaperNmsSpawnPackets.despawn(entityId).execute(it) } - V1_21_11SurfGlowingApiImpl.INSTANCE.removeGlowing(entityId, playerData.uuid) + V1_21_11SurfGlowingApiImpl.removeGlowing(entityId, playerData.uuid) } private fun initialize() { diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/block/BlockPlayerData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/block/BlockPlayerData.kt index be3f577be..c8f7d9e8a 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/block/BlockPlayerData.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/block/BlockPlayerData.kt @@ -1,11 +1,11 @@ package dev.slne.surf.api.paper.server.nms.v1_21_11.glow.block -import dev.slne.surf.api.core.util.mutableObject2ObjectMapOf import dev.slne.surf.api.paper.extensions.server import org.bukkit.Location import java.util.* +import java.util.concurrent.ConcurrentHashMap class BlockPlayerData(val uuid: UUID) { - val blocks = mutableObject2ObjectMapOf() + val blocks = ConcurrentHashMap() val player get() = server.getPlayer(uuid) } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/entity/EntityGlowingData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/entity/EntityGlowingData.kt index 3dcf23f3d..2b42fa0f5 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/entity/EntityGlowingData.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/entity/EntityGlowingData.kt @@ -10,6 +10,7 @@ import glm_.and import glm_.or import net.minecraft.ChatFormatting +@NmsUseWithCaution data class EntityGlowingData( val playerData: EntityPlayerData, val entityId: Int, @@ -25,9 +26,9 @@ data class EntityGlowingData( val operation = PacketOperation.start() if (teamData.markSeen(playerData.uuid)) { - operation.add(V1_21_11SurfPaperNmsGlowingBridgeImpl.INSTANCE.createTeam(teamData)) + operation.add(V1_21_11SurfPaperNmsGlowingBridgeImpl.createTeam(teamData)) } - operation.add(V1_21_11SurfPaperNmsGlowingBridgeImpl.INSTANCE.addEntityToTeam(teamData, teamId)) + operation.add(V1_21_11SurfPaperNmsGlowingBridgeImpl.addEntityToTeam(teamData, teamId)) return operation } @@ -40,7 +41,7 @@ data class EntityGlowingData( val operation = PacketOperation.start() if (teamData.removeSeen(playerData.uuid)) { operation.add( - V1_21_11SurfPaperNmsGlowingBridgeImpl.INSTANCE.removeEntityFromTeam( + V1_21_11SurfPaperNmsGlowingBridgeImpl.removeEntityFromTeam( teamData, teamId ) @@ -58,7 +59,7 @@ data class EntityGlowingData( otherFlags and V1_21_11SurfGlowingApiImpl.glowingFlag.inv() } - return V1_21_11SurfPaperNmsGlowingBridgeImpl.INSTANCE.setEntityFlags( + return V1_21_11SurfPaperNmsGlowingBridgeImpl.setEntityFlags( entityId, newFlags, ignorePacket diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/entity/EntityPlayerData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/entity/EntityPlayerData.kt index acefb4310..58b132da9 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/entity/EntityPlayerData.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/entity/EntityPlayerData.kt @@ -1,8 +1,10 @@ package dev.slne.surf.api.paper.server.nms.v1_21_11.glow.entity +import dev.slne.surf.api.paper.nms.NmsUseWithCaution import java.util.* import java.util.concurrent.ConcurrentHashMap +@NmsUseWithCaution data class EntityPlayerData(val uuid: UUID) { val entities = ConcurrentHashMap() } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/V1_21_11PacketRegistry.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/V1_21_11PacketRegistry.kt index 01f7b751a..e11d7a13f 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/V1_21_11PacketRegistry.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/listener/packets/V1_21_11PacketRegistry.kt @@ -1,6 +1,5 @@ package dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets -import dev.slne.surf.api.core.util.mutableObject2ObjectMapOf import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.listener.packets.clientbound.NmsClientboundPacket import dev.slne.surf.api.paper.nms.listener.packets.serverbound.NmsServerboundPacket @@ -10,6 +9,7 @@ import dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.serverbound. import dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.serverbound.V1_21_11RenameItemPacketImpl import dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.serverbound.V1_21_11ServerboundCustomPayloadPacketImpl import dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.serverbound.V1_21_11SignUpdatePacketImpl +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap import net.minecraft.network.protocol.Packet import net.minecraft.network.protocol.common.ClientCommonPacketListener import net.minecraft.network.protocol.common.ClientboundDisconnectPacket @@ -23,10 +23,10 @@ import kotlin.reflect.KClass @OptIn(NmsUseWithCaution::class) object V1_21_11PacketRegistry { - private val SERVERBOUND_PACKETS = - mutableObject2ObjectMapOf>, ServerboundPacketFactory<*, *>>() - private val CLIENTBOUND_PACKETS = - mutableObject2ObjectMapOf>, ClientboundPacketFactory<*, *>>() + private typealias PacketMap = Object2ObjectOpenHashMap>, F> + + private val SERVERBOUND_PACKETS = PacketMap>() + private val CLIENTBOUND_PACKETS = PacketMap>() init { // @formatter:off diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/listener/V1_21_11GlowingPacketListener.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/listener/V1_21_11GlowingPacketListener.kt index b6d459a5d..28d1dc2b6 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/listener/V1_21_11GlowingPacketListener.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/listener/V1_21_11GlowingPacketListener.kt @@ -61,7 +61,7 @@ object V1_21_11GlowingPacketListener : PacketListener { } val playerData = V1_21_11SurfGlowingApiImpl.getEntityPlayerData(player) ?: return packet - val glowingData = playerData.entities.get(packet.id) ?: return packet + val glowingData = playerData.entities[packet.id] ?: return packet val incoming = packet.packedItems var flagsFound = false var edited = false diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt index 0eaa9e551..0af20fc61 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt @@ -2,6 +2,7 @@ package dev.slne.surf.api.paper.server.nms.v26_1 import com.google.auto.service.AutoService import dev.slne.surf.api.paper.glow.SurfGlowingApi +import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge import dev.slne.surf.api.paper.nms.bridges.* import dev.slne.surf.api.paper.nms.bridges.packets.SurfPaperNmsPacketBridges @@ -27,15 +28,12 @@ import dev.slne.surf.api.paper.server.nms.v26_1.packet.lore.V26_1PacketLoreListe import dev.slne.surf.api.paper.server.nms.v26_1.packet.lore.V26_1PacketLoreRegistry import dev.slne.surf.api.paper.server.nms.v26_1.reflection.V26_1Reflection import dev.slne.surf.api.paper.server.nms.v26_1.region.V26_1TickThreadGuard -import org.bukkit.plugin.java.JavaPlugin +@OptIn(NmsUseWithCaution::class) @AutoService(NmsProvider::class) class V26_1NmsProvider : NmsProvider { override val version: NmsVersion = NmsVersion.V26_1 - private var glowingBridge: V26_1SurfPaperNmsGlowingBridgeImpl? = null - private var glowingApi: V26_1SurfGlowingApiImpl? = null - override fun createNmsBridge(): SurfPaperNmsBridge = V26_1SurfPaperNmsBridgeImpl() override fun createCommonBridge(): SurfPaperNmsCommonBridge = V26_1SurfPaperNmsCommonBridgeImpl() @@ -45,14 +43,11 @@ class V26_1NmsProvider : NmsProvider { override fun createItemBridge(): SurfPaperNmsItemBridge = V26_1SurfPaperNmsItemBridgeImpl() override fun createNbtBridge(): SurfPaperNmsNbtBridge = V26_1SurfPaperNmsNbtBridgeImpl() - override fun createGlowingBridge(): SurfPaperNmsGlowingBridge { - return glowingBridge ?: V26_1SurfPaperNmsGlowingBridgeImpl().also { - glowingBridge = it - V26_1SurfPaperNmsGlowingBridgeImpl.INSTANCE = it - } - } + override fun createGlowingBridge(): SurfPaperNmsGlowingBridge = V26_1SurfPaperNmsGlowingBridgeImpl + + override fun createStatsBridge(): SurfPaperNmsStatsBridge = + V26_1SurfPaperNmsStatsBridgeImpl() - override fun createStatsBridge(): SurfPaperNmsStatsBridge = V26_1SurfPaperNmsStatsBridgeImpl() override fun createLootTableBridge(): SurfPaperNmsLootTableBridge = V26_1SurfPaperNmsLootTableBridgeImpl() @@ -78,21 +73,14 @@ class V26_1NmsProvider : NmsProvider { V26_1SurfPaperNmsPlayerToastPacketsImpl() override fun createTickThreadGuard(): TickThreadGuard = V26_1TickThreadGuard() - override fun createPacketBridgeHandler(): NmsPacketBridgeHandler = V26_1NmsPacketBridgeHandler() + override fun createPacketBridgeHandler(): NmsPacketBridgeHandler = + V26_1NmsPacketBridgeHandler() + override fun createPacketLoreRegistry(): PacketLoreRegistry = V26_1PacketLoreRegistry() override fun createGlowingLifecycleHandler(): GlowingLifecycleHandler = V26_1GlowingLifecycleHandler() - override fun createGlowingApi(): SurfGlowingApi { - // Ensure glowing bridge is initialized before the API uses it - createGlowingBridge() - - val plugin = JavaPlugin.getProvidingPlugin(V26_1NmsProvider::class.java) as JavaPlugin - val api = V26_1SurfGlowingApiImpl(plugin) - V26_1SurfGlowingApiImpl.INSTANCE = api - glowingApi = api - return api - } + override fun createGlowingApi(): SurfGlowingApi = V26_1SurfGlowingApiImpl override fun createPacketListeners(): List = listOf( V26_1PacketLoreListener, diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsBridgeImpl.kt index 7c6d1ef4a..3a9b96b18 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsBridgeImpl.kt @@ -9,19 +9,18 @@ import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge import dev.slne.surf.api.paper.nms.listener.packets.clientbound.NmsClientboundPacket import dev.slne.surf.api.paper.nms.listener.packets.serverbound.NmsServerboundPacket import dev.slne.surf.api.paper.packet.listener.listener.PacketListenerResult -import dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.V26_1NmsPacketImpl import org.bukkit.entity.Player import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.CopyOnWriteArraySet @NmsUseWithCaution class V26_1SurfPaperNmsBridgeImpl : SurfPaperNmsBridge { + private typealias PacketListenerMap = ConcurrentHashMap, CopyOnWriteArraySet> + private val log = logger() - private val serverboundPacketListeners = - ConcurrentHashMap, CopyOnWriteArraySet>>() - private val clientboundPacketListeners = - ConcurrentHashMap, CopyOnWriteArraySet>>() + private val serverboundPacketListeners = PacketListenerMap>() + private val clientboundPacketListeners = PacketListenerMap>() override fun registerServerboundPacketListener(listener: NmsServerboundPacketListener<*>) { val packetClass = listener.packetClass diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsGlowingBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsGlowingBridgeImpl.kt index dc055d9e8..cddc75ca0 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsGlowingBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsGlowingBridgeImpl.kt @@ -14,7 +14,7 @@ import net.minecraft.network.syncher.SynchedEntityData.DataValue import org.bukkit.entity.Entity @NmsUseWithCaution -class V26_1SurfPaperNmsGlowingBridgeImpl : SurfPaperNmsGlowingBridge { +object V26_1SurfPaperNmsGlowingBridgeImpl : SurfPaperNmsGlowingBridge { fun createTeam(data: V26_1TeamData): PacketOperation = V26_1PacketOperationImpl.simple { ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(data.team, true) @@ -53,9 +53,4 @@ class V26_1SurfPaperNmsGlowingBridgeImpl : SurfPaperNmsGlowingBridge { val dataAccessor = V26_1Reflection.ENTITY_PROXY.getDataFlagsSharedId() return entity.toNms().entityData.get(dataAccessor) } - - companion object { - lateinit var INSTANCE: V26_1SurfPaperNmsGlowingBridgeImpl - internal set - } } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsItemBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsItemBridgeImpl.kt index 5b75ad965..b9a619d83 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsItemBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsItemBridgeImpl.kt @@ -3,13 +3,13 @@ package dev.slne.surf.api.paper.server.nms.v26_1.bridges import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsItemBridge import dev.slne.surf.api.paper.server.nms.v26_1.extensions.nms +import dev.slne.surf.api.paper.server.nms.v26_1.reflection.V26_1Reflection import net.minecraft.core.component.DataComponentMap import net.minecraft.core.component.DataComponents import org.bukkit.inventory.ItemType @NmsUseWithCaution class V26_1SurfPaperNmsItemBridgeImpl : SurfPaperNmsItemBridge { - override fun setDefaultMaxStackSize(item: ItemType, maxStackSize: Int) { require(maxStackSize in 1..100) { "Max stack size must be between 1 and 100" } @@ -19,6 +19,7 @@ class V26_1SurfPaperNmsItemBridgeImpl : SurfPaperNmsItemBridge { .set(DataComponents.MAX_STACK_SIZE, maxStackSize) .build() - nmsItem.builtInRegistryHolder().bindComponents(updatedComponents) + + V26_1Reflection.ITEM_PROXY.setComponents(nmsItem, updatedComponents) } } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsNbtBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsNbtBridgeImpl.kt index ab61073e0..aed945104 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsNbtBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsNbtBridgeImpl.kt @@ -16,7 +16,6 @@ import kotlin.jvm.optionals.getOrNull @NmsUseWithCaution class V26_1SurfPaperNmsNbtBridgeImpl : SurfPaperNmsNbtBridge { - private val log = logger() override fun makeItemStackEntityInvisible( diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1GlowingLifecycleHandler.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1GlowingLifecycleHandler.kt index 72f668b4e..dd4e4cea2 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1GlowingLifecycleHandler.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1GlowingLifecycleHandler.kt @@ -1,5 +1,6 @@ package dev.slne.surf.api.paper.server.nms.v26_1.glow +import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation import dev.slne.surf.api.paper.nms.common.GlowingLifecycleHandler import dev.slne.surf.api.paper.util.chunkX @@ -7,6 +8,7 @@ import dev.slne.surf.api.paper.util.chunkZ import org.bukkit.World import org.bukkit.entity.Player +@NmsUseWithCaution class V26_1GlowingLifecycleHandler : GlowingLifecycleHandler { override fun removeAllGlowingOnQuit(player: Player) { V26_1SurfGlowingApiImpl.removeAllGlowingOnQuit(player) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt index e7f9d91a7..0ffb35033 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt @@ -7,7 +7,7 @@ import dev.slne.surf.api.paper.glow.SurfGlowingApi import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation import dev.slne.surf.api.paper.server.nms.v26_1.bridges.V26_1SurfPaperNmsGlowingBridgeImpl -import dev.slne.surf.api.paper.server.nms.v26_1.glow.block.V26_1BlockGlowingData +import dev.slne.surf.api.paper.server.nms.v26_1.glow.block.BlockGlowingData import dev.slne.surf.api.paper.server.nms.v26_1.glow.block.BlockPlayerData import dev.slne.surf.api.paper.server.nms.v26_1.glow.entity.EntityGlowingData import dev.slne.surf.api.paper.server.nms.v26_1.glow.entity.EntityPlayerData @@ -24,7 +24,11 @@ import java.util.* import java.util.concurrent.ConcurrentHashMap @NmsUseWithCaution -class V26_1SurfGlowingApiImpl(private val plugin: JavaPlugin) : SurfGlowingApi { +object V26_1SurfGlowingApiImpl : SurfGlowingApi { + private val entityPlayerData = ConcurrentHashMap() + private val blockPlayerData = ConcurrentHashMap() + + val glowingFlag = 1 shl V26_1Reflection.ENTITY_PROXY.getFlagGlowing() override fun makeGlowing( target: Entity, @@ -36,7 +40,7 @@ class V26_1SurfGlowingApiImpl(private val plugin: JavaPlugin) : SurfGlowingApi { teamIdFor(target), viewer, color, - V26_1SurfPaperNmsGlowingBridgeImpl.INSTANCE.getCurrentFlags(target) + V26_1SurfPaperNmsGlowingBridgeImpl.getCurrentFlags(target) ) } @@ -50,7 +54,7 @@ class V26_1SurfGlowingApiImpl(private val plugin: JavaPlugin) : SurfGlowingApi { val nmsColor = color?.let { PaperAdventure.asVanilla(it) } val uuid = viewer.uniqueId val playerData = entityPlayerData.computeIfAbsent(uuid) { EntityPlayerData(uuid) } - val glowingData = playerData.entities.get(targetId) + val glowingData = playerData.entities[targetId] val operation = PacketOperation.start() if (glowingData == null) { @@ -61,7 +65,7 @@ class V26_1SurfGlowingApiImpl(private val plugin: JavaPlugin) : SurfGlowingApi { nmsColor, otherFlags ) - playerData.entities.put(targetId, newData) + playerData.entities[targetId] = newData operation.add(newData.sendGlowingFlag(enabled = true, ignorePacket = true)) if (nmsColor != null) { @@ -95,9 +99,10 @@ class V26_1SurfGlowingApiImpl(private val plugin: JavaPlugin) : SurfGlowingApi { val blockData = playerData.blocks[blockLocation] if (blockData == null) { - val newData = V26_1BlockGlowingData(playerData, blockLocation, color) + val newData = BlockGlowingData(playerData, blockLocation, color) playerData.blocks[blockLocation] = newData + val plugin = JavaPlugin.getProvidingPlugin(javaClass) plugin.launch(plugin.entityDispatcher(viewer)) { if (viewer.isChunkVisible(blockLocation)) { newData.spawn().execute(viewer) @@ -148,26 +153,17 @@ class V26_1SurfGlowingApiImpl(private val plugin: JavaPlugin) : SurfGlowingApi { private fun teamIdFor(entity: Entity) = (entity as? Player)?.name ?: entity.uniqueId.toString() - companion object { - lateinit var INSTANCE: V26_1SurfGlowingApiImpl - internal set - - private val entityPlayerData = ConcurrentHashMap() - private val blockPlayerData = ConcurrentHashMap() - val glowingFlag = 1 shl V26_1Reflection.ENTITY_PROXY.getFlagGlowing() + fun getEntityPlayerData(player: Player): EntityPlayerData? = + entityPlayerData[player.uniqueId] - fun getEntityPlayerData(player: Player): EntityPlayerData? = - entityPlayerData[player.uniqueId] + fun getBlockPlayerData(player: Player): BlockPlayerData? = + blockPlayerData[player.uniqueId] - fun getBlockPlayerData(player: Player): BlockPlayerData? = - blockPlayerData[player.uniqueId] - - fun removeAllGlowingOnQuit(player: Player) { - val uuid = player.uniqueId - V26_1TeamData.removeFromAll(uuid) - entityPlayerData.remove(uuid)?.entities?.clear() - blockPlayerData.remove(uuid)?.blocks?.clear() - } + fun removeAllGlowingOnQuit(player: Player) { + val uuid = player.uniqueId + V26_1TeamData.removeFromAll(uuid) + entityPlayerData.remove(uuid)?.entities?.clear() + blockPlayerData.remove(uuid)?.blocks?.clear() } } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/V26_1BlockGlowingData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/BlockGlowingData.kt similarity index 90% rename from surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/V26_1BlockGlowingData.kt rename to surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/BlockGlowingData.kt index e7d3e29e3..403bf294f 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/V26_1BlockGlowingData.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/BlockGlowingData.kt @@ -17,7 +17,7 @@ import org.bukkit.Location import java.util.* @OptIn(NmsUseWithCaution::class) -class V26_1BlockGlowingData( +class BlockGlowingData( val playerData: BlockPlayerData, val location: Location, var color: NamedTextColor, @@ -45,16 +45,15 @@ class V26_1BlockGlowingData( 0.0 ) } - val invisibleOperation = V26_1SurfPaperNmsGlowingBridgeImpl.INSTANCE - .setEntityFlags(entityId, invisibleFlag) - + val invisibleOperation = V26_1SurfPaperNmsGlowingBridgeImpl.setEntityFlags(entityId, invisibleFlag) + return spawnOperation + invisibleOperation } fun updateColor() { val player = playerData.player ?: return - V26_1SurfGlowingApiImpl.INSTANCE.makeGlowing( + V26_1SurfGlowingApiImpl.makeGlowing( entityId, uuid.toString(), player, @@ -65,7 +64,7 @@ class V26_1BlockGlowingData( fun remove() { playerData.player?.let { SurfPaperNmsSpawnPackets.despawn(entityId).execute(it) } - V26_1SurfGlowingApiImpl.INSTANCE.removeGlowing(entityId, playerData.uuid) + V26_1SurfGlowingApiImpl.removeGlowing(entityId, playerData.uuid) } private fun initialize() { diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/BlockPlayerData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/BlockPlayerData.kt index 9002cbddf..21bb86ba7 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/BlockPlayerData.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/block/BlockPlayerData.kt @@ -1,11 +1,11 @@ package dev.slne.surf.api.paper.server.nms.v26_1.glow.block -import dev.slne.surf.api.core.util.mutableObject2ObjectMapOf import dev.slne.surf.api.paper.extensions.server import org.bukkit.Location import java.util.* +import java.util.concurrent.ConcurrentHashMap class BlockPlayerData(val uuid: UUID) { - val blocks = mutableObject2ObjectMapOf() + val blocks = ConcurrentHashMap() val player get() = server.getPlayer(uuid) } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityGlowingData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityGlowingData.kt index fb7370f7b..8eb57d159 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityGlowingData.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityGlowingData.kt @@ -10,6 +10,7 @@ import glm_.and import glm_.or import net.minecraft.ChatFormatting +@NmsUseWithCaution data class EntityGlowingData( val playerData: EntityPlayerData, val entityId: Int, @@ -25,9 +26,9 @@ data class EntityGlowingData( val operation = PacketOperation.start() if (teamData.markSeen(playerData.uuid)) { - operation.add(V26_1SurfPaperNmsGlowingBridgeImpl.INSTANCE.createTeam(teamData)) + operation.add(V26_1SurfPaperNmsGlowingBridgeImpl.createTeam(teamData)) } - operation.add(V26_1SurfPaperNmsGlowingBridgeImpl.INSTANCE.addEntityToTeam(teamData, teamId)) + operation.add(V26_1SurfPaperNmsGlowingBridgeImpl.addEntityToTeam(teamData, teamId)) return operation } @@ -40,7 +41,7 @@ data class EntityGlowingData( val operation = PacketOperation.start() if (teamData.removeSeen(playerData.uuid)) { operation.add( - V26_1SurfPaperNmsGlowingBridgeImpl.INSTANCE.removeEntityFromTeam( + V26_1SurfPaperNmsGlowingBridgeImpl.removeEntityFromTeam( teamData, teamId ) @@ -58,7 +59,7 @@ data class EntityGlowingData( otherFlags and V26_1SurfGlowingApiImpl.glowingFlag.inv() } - return V26_1SurfPaperNmsGlowingBridgeImpl.INSTANCE.setEntityFlags( + return V26_1SurfPaperNmsGlowingBridgeImpl.setEntityFlags( entityId, newFlags, ignorePacket diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityPlayerData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityPlayerData.kt index 7bf507177..652f71426 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityPlayerData.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityPlayerData.kt @@ -1,8 +1,10 @@ package dev.slne.surf.api.paper.server.nms.v26_1.glow.entity +import dev.slne.surf.api.paper.nms.NmsUseWithCaution import java.util.* import java.util.concurrent.ConcurrentHashMap +@NmsUseWithCaution data class EntityPlayerData(val uuid: UUID) { val entities = ConcurrentHashMap() } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/V26_1PacketRegistry.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/V26_1PacketRegistry.kt index 1e7a01666..00e8fac6c 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/V26_1PacketRegistry.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/V26_1PacketRegistry.kt @@ -1,6 +1,5 @@ package dev.slne.surf.api.paper.server.nms.v26_1.listener.packets -import dev.slne.surf.api.core.util.mutableObject2ObjectMapOf import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.listener.packets.clientbound.NmsClientboundPacket import dev.slne.surf.api.paper.nms.listener.packets.serverbound.NmsServerboundPacket @@ -10,6 +9,7 @@ import dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.serverbound.V26 import dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.serverbound.V26_1RenameItemPacketImpl import dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.serverbound.V26_1ServerboundCustomPayloadPacketImpl import dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.serverbound.V26_1SignUpdatePacketImpl +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap import net.minecraft.network.protocol.Packet import net.minecraft.network.protocol.common.ClientCommonPacketListener import net.minecraft.network.protocol.common.ClientboundDisconnectPacket @@ -23,10 +23,10 @@ import kotlin.reflect.KClass @OptIn(NmsUseWithCaution::class) object V26_1PacketRegistry { - private val SERVERBOUND_PACKETS = - mutableObject2ObjectMapOf>, ServerboundPacketFactory<*, *>>() - private val CLIENTBOUND_PACKETS = - mutableObject2ObjectMapOf>, ClientboundPacketFactory<*, *>>() + private typealias PacketMap = Object2ObjectOpenHashMap>, F> + + private val SERVERBOUND_PACKETS = PacketMap>() + private val CLIENTBOUND_PACKETS = PacketMap>() init { // @formatter:off diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1GlowingPacketListener.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1GlowingPacketListener.kt index 41ec839cf..9a43863f8 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1GlowingPacketListener.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1GlowingPacketListener.kt @@ -61,7 +61,7 @@ object V26_1GlowingPacketListener : PacketListener { } val playerData = V26_1SurfGlowingApiImpl.getEntityPlayerData(player) ?: return packet - val glowingData = playerData.entities.get(packet.id) ?: return packet + val glowingData = playerData.entities[packet.id] ?: return packet val incoming = packet.packedItems var flagsFound = false var edited = false diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ItemProxy.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ItemProxy.kt new file mode 100644 index 000000000..f8d3e202a --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ItemProxy.kt @@ -0,0 +1,12 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.reflection + +import net.minecraft.core.component.DataComponentMap +import net.minecraft.world.item.Item +import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldSetter +import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies + +@Proxies(Item::class) +interface V26_1ItemProxy { + @FieldSetter("components") + fun setComponents(item: Item, components: DataComponentMap) +} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1Reflection.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1Reflection.kt index fb6e60e5d..fa245fa3e 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1Reflection.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1Reflection.kt @@ -11,6 +11,8 @@ object V26_1Reflection { private set lateinit var ENTITY_PROXY: V26_1EntityProxy private set + lateinit var ITEM_PROXY: V26_1ItemProxy + private set lateinit var SERVER_CONNECTION_LISTENER_PROXY: V26_1ServerConnectionListenerProxy private set lateinit var VANILLA_ARGUMENT_PROVIDER_IMPL_PROXY: V26_1VanillaArgumentProviderImplProxy @@ -25,11 +27,13 @@ object V26_1Reflection { SERVER_STATS_COUNTER_PROXY = proxyFactory.reflectionProxy() ENTITY_PROXY = proxyFactory.reflectionProxy() + ITEM_PROXY = proxyFactory.reflectionProxy() SERVER_CONNECTION_LISTENER_PROXY = proxyFactory.reflectionProxy() VANILLA_ARGUMENT_PROVIDER_IMPL_PROXY = SurfReflection.createProxy() - VANILLA_ARGUMENT_PROVIDER_PROXY = SurfReflection.createProxy() + VANILLA_ARGUMENT_PROVIDER_PROXY = + SurfReflection.createProxy() // gc the remapper System.gc() diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider new file mode 100644 index 000000000..b5e249f89 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider @@ -0,0 +1 @@ +dev.slne.surf.api.paper.server.nms.v26_1.V26_1NmsProvider From 84a22af34f8d73d1459c3760295943da95f05dd6 Mon Sep 17 00:00:00 2001 From: twisti <76837088+twisti-dev@users.noreply.github.com> Date: Wed, 15 Apr 2026 17:10:01 +0200 Subject: [PATCH 20/34] =?UTF-8?q?=E2=9C=A8=20feat(nms):=20enhance=20NMS=20?= =?UTF-8?q?support=20with=20new=20internal=20bridge=20and=20refactor=20pac?= =?UTF-8?q?ket=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add InternalNmsBridge interface for improved packet handling - update NmsProvider to use getPacketBridgeHandler method - apply NmsUseWithCaution annotation to relevant classes - suppress ClassName warnings for consistency in naming conventions --- .../surf/api/paper/nms/common/NmsProvider.kt | 2 +- .../V1_21_11NmsPacketBridgeHandler.kt | 2 +- .../nms/v1_21_11/V1_21_11NmsProvider.kt | 3 +- .../nms/v26_1/V26_1NmsPacketBridgeHandler.kt | 3 +- .../server/nms/v26_1/V26_1NmsProvider.kt | 4 +- .../bridges/V26_1SurfPaperNmsBridgeImpl.kt | 1 + ...fPaperNmsCommandArgumentTypesBridgeImpl.kt | 1 + .../V26_1SurfPaperNmsCommonBridgeImpl.kt | 1 + .../V26_1SurfPaperNmsEntityBridgeImpl.kt | 1 + .../V26_1SurfPaperNmsGlowingBridgeImpl.kt | 1 + .../V26_1SurfPaperNmsItemBridgeImpl.kt | 1 + .../V26_1SurfPaperNmsLootTableBridgeImpl.kt | 1 + .../bridges/V26_1SurfPaperNmsNbtBridgeImpl.kt | 1 + .../V26_1SurfPaperNmsStatsBridgeImpl.kt | 1 + .../packets/V26_1PacketOperationImpl.kt | 1 + .../V26_1SurfPaperNmsPacketBridgesImpl.kt | 1 + .../V26_1SurfPaperNmsBlockPacketsImpl.kt | 1 + .../V26_1SurfPaperNmsSpawnPacketsImpl.kt | 2 +- .../V26_1SurfPaperNmsPlayerChatPacketsImpl.kt | 1 + .../V26_1SurfPaperNmsPlayerPacketsImpl.kt | 1 + ...V26_1SurfPaperNmsPlayerToastPacketsImpl.kt | 1 + .../glow/V26_1GlowingLifecycleHandler.kt | 1 + .../nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt | 1 + .../server/nms/v26_1/glow/V26_1TeamData.kt | 1 + .../v26_1/glow/entity/EntityGlowingData.kt | 1 + .../nms/v26_1/glow/entity/EntityPlayerData.kt | 1 + .../listener/packets/V26_1NmsPacketImpl.kt | 1 + .../listener/packets/V26_1PacketRegistry.kt | 1 + .../V26_1ClientboundDisconnectPacketImpl.kt | 1 + .../V26_1ClientboundSystemChatPacketImpl.kt | 1 + .../V26_1NmsClientboundPacketImpl.kt | 1 + .../V26_1CommandSuggestionPacketImpl.kt | 1 + .../V26_1NmsServerboundPacketImpl.kt | 1 + .../serverbound/V26_1RenameItemPacketImpl.kt | 1 + ...V26_1ServerboundCustomPayloadPacketImpl.kt | 1 + .../serverbound/V26_1SignUpdatePacketImpl.kt | 1 + .../listener/V26_1GlowingPacketListener.kt | 1 + .../packet/lore/V26_1PacketLoreListener.kt | 1 + .../packet/lore/V26_1PacketLoreRegistry.kt | 1 + .../nms/v26_1/reflection/V26_1EntityProxy.kt | 1 + .../nms/v26_1/reflection/V26_1ItemProxy.kt | 1 + .../nms/v26_1/reflection/V26_1Reflection.kt | 1 + .../V26_1ServerConnectionListenerProxy.kt | 1 + .../V26_1ServerStatsCounterProxy.kt | 1 + .../V26_1VanillaArgumentProviderImplProxy.kt | 1 + .../V26_1VanillaArgumentProviderProxy.kt | 2 +- .../nms/v26_1/region/V26_1TickThreadGuard.kt | 2 +- ...slne.surf.api.paper.nms.common.NmsProvider | 1 - .../surf-api-paper-server/build.gradle.kts | 1 + .../surf/api/paper/server/PaperInstance.kt | 2 + .../paper/server/impl/glow/GlowingListener.kt | 2 + .../server/impl/nms/SurfPaperNmsBridgeImpl.kt | 134 ------------ ...fPaperNmsCommandArgumentTypesBridgeImpl.kt | 109 --------- .../bridges/SurfPaperNmsCommonBridgeImpl.kt | 92 -------- .../bridges/SurfPaperNmsEntityBridgeImpl.kt | 55 ----- .../nms/bridges/SurfPaperNmsItemBridgeImpl.kt | 26 --- .../SurfPaperNmsLootTableBridgeImpl.kt | 55 ----- .../nms/bridges/SurfPaperNmsNbtBridgeImpl.kt | 63 ------ .../bridges/SurfPaperNmsStatsBridgeImpl.kt | 23 -- .../bridges/packets/PacketOperationImpl.kt | 115 ---------- .../packets/SurfPaperNmsPacketBridgesImpl.kt | 14 -- .../block/SurfPaperNmsBlockPacketsImpl.kt | 34 --- .../entity/SurfPaperNmsSpawnPacketsImpl.kt | 207 ------------------ .../SurfPaperNmsPlayerChatPacketsImpl.kt | 64 ------ .../player/SurfPaperNmsPlayerPacketsImpl.kt | 56 ----- .../SurfPaperNmsPlayerToastPacketsImpl.kt | 60 ----- .../nms/listener/packets/NmsPacketImpl.kt | 24 -- .../nms/listener/packets/PacketRegistry.kt | 78 ------- .../ClientboundDisconnectPacketImpl.kt | 14 -- .../ClientboundSystemChatPacketImpl.kt | 25 --- .../clientbound/NmsClientboundPacketImpl.kt | 12 - .../CommandSuggestionPacketImpl.kt | 13 -- .../serverbound/NmsServerboundPacketImpl.kt | 10 - .../serverbound/RenameItemPacketImpl.kt | 11 - .../ServerboundCustomPayloadPacketImpl.kt | 42 ---- .../serverbound/SignUpdatePacketImpl.kt | 19 -- .../impl/packet/SurfPaperPacketApiImpl.kt | 2 + .../server/impl/region/TickThreadGuardImpl.kt | 67 ------ .../surf/api/paper/server/nms/AdventureNBT.kt | 96 -------- .../server/nms/bridge/InternalNmsBridge.kt | 24 ++ .../api/paper/server/nms/nms-extensions.kt | 132 ----------- .../paper/server/packet/PacketApiLoader.kt | 1 + .../packet/listener/PlayerChannelInjector.kt | 10 +- .../lore/PluginDisablePacketLoreListener.kt | 2 + .../paper/server/proxy/SurfGlowingApiProxy.kt | 2 + .../server/proxy/SurfPaperNmsBridgeProxy.kt | 15 ++ .../server/proxy/TickThreadGuardProxy.kt | 2 + 87 files changed, 105 insertions(+), 1668 deletions(-) delete mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/SurfPaperNmsBridgeImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsCommandArgumentTypesBridgeImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsCommonBridgeImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsEntityBridgeImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsItemBridgeImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsLootTableBridgeImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsNbtBridgeImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsStatsBridgeImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/PacketOperationImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/SurfPaperNmsPacketBridgesImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/block/SurfPaperNmsBlockPacketsImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/entity/SurfPaperNmsSpawnPacketsImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerChatPacketsImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerPacketsImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerToastPacketsImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/NmsPacketImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/PacketRegistry.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/clientbound/ClientboundDisconnectPacketImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/clientbound/ClientboundSystemChatPacketImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/clientbound/NmsClientboundPacketImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/serverbound/CommandSuggestionPacketImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/serverbound/NmsServerboundPacketImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/serverbound/RenameItemPacketImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/serverbound/ServerboundCustomPayloadPacketImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/serverbound/SignUpdatePacketImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/region/TickThreadGuardImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/nms/AdventureNBT.kt create mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/nms/bridge/InternalNmsBridge.kt create mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsBridgeProxy.kt diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt index 5c875a8c7..c75c50863 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt @@ -54,7 +54,7 @@ interface NmsProvider { /** * Creates the packet bridge handler for wrapping/unwrapping NMS packets. */ - fun createPacketBridgeHandler(): NmsPacketBridgeHandler + fun getPacketBridgeHandler(): NmsPacketBridgeHandler /** * Creates the packet lore registry for managing version-specific lore handlers. diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsPacketBridgeHandler.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsPacketBridgeHandler.kt index d812cebbf..7bb6f7497 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsPacketBridgeHandler.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsPacketBridgeHandler.kt @@ -10,7 +10,7 @@ import dev.slne.surf.api.paper.server.nms.v1_21_11.listener.packets.V1_21_11Pack import net.minecraft.network.protocol.Packet @NmsUseWithCaution -class V1_21_11NmsPacketBridgeHandler : NmsPacketBridgeHandler { +object V1_21_11NmsPacketBridgeHandler : NmsPacketBridgeHandler { @Suppress("UNCHECKED_CAST") override fun wrapServerboundPacket(nmsPacket: Any): NmsServerboundPacket? { diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt index a045b679c..00372a673 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt @@ -73,8 +73,7 @@ class V1_21_11NmsProvider : NmsProvider { V1_21_11SurfPaperNmsPlayerToastPacketsImpl() override fun createTickThreadGuard(): TickThreadGuard = V1_21_11TickThreadGuard() - override fun createPacketBridgeHandler(): NmsPacketBridgeHandler = - V1_21_11NmsPacketBridgeHandler() + override fun getPacketBridgeHandler(): NmsPacketBridgeHandler = V1_21_11NmsPacketBridgeHandler override fun createPacketLoreRegistry(): PacketLoreRegistry = V1_21_11PacketLoreRegistry() override fun createGlowingLifecycleHandler(): GlowingLifecycleHandler = diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsPacketBridgeHandler.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsPacketBridgeHandler.kt index 892270ff0..d714b86a4 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsPacketBridgeHandler.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsPacketBridgeHandler.kt @@ -10,7 +10,8 @@ import dev.slne.surf.api.paper.server.nms.v26_1.listener.packets.V26_1PacketRegi import net.minecraft.network.protocol.Packet @NmsUseWithCaution -class V26_1NmsPacketBridgeHandler : NmsPacketBridgeHandler { +@Suppress("ClassName") +object V26_1NmsPacketBridgeHandler : NmsPacketBridgeHandler { @Suppress("UNCHECKED_CAST") override fun wrapServerboundPacket(nmsPacket: Any): NmsServerboundPacket? { diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt index 0af20fc61..038ba54b9 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt @@ -29,6 +29,7 @@ import dev.slne.surf.api.paper.server.nms.v26_1.packet.lore.V26_1PacketLoreRegis import dev.slne.surf.api.paper.server.nms.v26_1.reflection.V26_1Reflection import dev.slne.surf.api.paper.server.nms.v26_1.region.V26_1TickThreadGuard +@Suppress("ClassName") @OptIn(NmsUseWithCaution::class) @AutoService(NmsProvider::class) class V26_1NmsProvider : NmsProvider { @@ -73,8 +74,7 @@ class V26_1NmsProvider : NmsProvider { V26_1SurfPaperNmsPlayerToastPacketsImpl() override fun createTickThreadGuard(): TickThreadGuard = V26_1TickThreadGuard() - override fun createPacketBridgeHandler(): NmsPacketBridgeHandler = - V26_1NmsPacketBridgeHandler() + override fun getPacketBridgeHandler(): NmsPacketBridgeHandler = V26_1NmsPacketBridgeHandler override fun createPacketLoreRegistry(): PacketLoreRegistry = V26_1PacketLoreRegistry() override fun createGlowingLifecycleHandler(): GlowingLifecycleHandler = diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsBridgeImpl.kt index 3a9b96b18..030a684b6 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsBridgeImpl.kt @@ -14,6 +14,7 @@ import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.CopyOnWriteArraySet @NmsUseWithCaution +@Suppress("ClassName") class V26_1SurfPaperNmsBridgeImpl : SurfPaperNmsBridge { private typealias PacketListenerMap = ConcurrentHashMap, CopyOnWriteArraySet> diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsCommandArgumentTypesBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsCommandArgumentTypesBridgeImpl.kt index 8ae2c5c8d..221c24dfe 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsCommandArgumentTypesBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsCommandArgumentTypesBridgeImpl.kt @@ -19,6 +19,7 @@ import java.lang.reflect.InvocationHandler import java.util.concurrent.ConcurrentHashMap @NmsUseWithCaution +@Suppress("ClassName") class V26_1SurfPaperNmsCommandArgumentTypesBridgeImpl : SurfPaperNmsCommandArgumentTypesBridge { override fun compoundTag(): ArgumentType<*> { diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsCommonBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsCommonBridgeImpl.kt index 859176ecb..c00cba923 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsCommonBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsCommonBridgeImpl.kt @@ -20,6 +20,7 @@ import org.bukkit.entity.Player import java.net.InetSocketAddress @NmsUseWithCaution +@Suppress("ClassName") class V26_1SurfPaperNmsCommonBridgeImpl : SurfPaperNmsCommonBridge { @Suppress("DEPRECATION") diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsEntityBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsEntityBridgeImpl.kt index 9fd00125b..afab07b30 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsEntityBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsEntityBridgeImpl.kt @@ -18,6 +18,7 @@ import org.bukkit.World import org.bukkit.entity.EntityType @NmsUseWithCaution +@Suppress("ClassName") class V26_1SurfPaperNmsEntityBridgeImpl : SurfPaperNmsEntityBridge { @Suppress("UnstableApiUsage") diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsGlowingBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsGlowingBridgeImpl.kt index cddc75ca0..904bcbd17 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsGlowingBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsGlowingBridgeImpl.kt @@ -14,6 +14,7 @@ import net.minecraft.network.syncher.SynchedEntityData.DataValue import org.bukkit.entity.Entity @NmsUseWithCaution +@Suppress("ClassName") object V26_1SurfPaperNmsGlowingBridgeImpl : SurfPaperNmsGlowingBridge { fun createTeam(data: V26_1TeamData): PacketOperation = V26_1PacketOperationImpl.simple { diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsItemBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsItemBridgeImpl.kt index b9a619d83..aa16475b7 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsItemBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsItemBridgeImpl.kt @@ -9,6 +9,7 @@ import net.minecraft.core.component.DataComponents import org.bukkit.inventory.ItemType @NmsUseWithCaution +@Suppress("ClassName") class V26_1SurfPaperNmsItemBridgeImpl : SurfPaperNmsItemBridge { override fun setDefaultMaxStackSize(item: ItemType, maxStackSize: Int) { require(maxStackSize in 1..100) { "Max stack size must be between 1 and 100" } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsLootTableBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsLootTableBridgeImpl.kt index ce78b3740..a08e77409 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsLootTableBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsLootTableBridgeImpl.kt @@ -18,6 +18,7 @@ import org.bukkit.inventory.ItemStack import kotlin.jvm.optionals.getOrNull @NmsUseWithCaution +@Suppress("ClassName") class V26_1SurfPaperNmsLootTableBridgeImpl : SurfPaperNmsLootTableBridge { override fun getDifferentLootTable( entity: LivingEntity, diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsNbtBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsNbtBridgeImpl.kt index aed945104..95268d1c8 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsNbtBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsNbtBridgeImpl.kt @@ -15,6 +15,7 @@ import org.bukkit.inventory.ItemStack import kotlin.jvm.optionals.getOrNull @NmsUseWithCaution +@Suppress("ClassName") class V26_1SurfPaperNmsNbtBridgeImpl : SurfPaperNmsNbtBridge { private val log = logger() diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsStatsBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsStatsBridgeImpl.kt index 72e50466e..c00489e6e 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsStatsBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsStatsBridgeImpl.kt @@ -7,6 +7,7 @@ import dev.slne.surf.api.paper.server.nms.v26_1.reflection.V26_1Reflection import org.bukkit.entity.Player @NmsUseWithCaution +@Suppress("ClassName") class V26_1SurfPaperNmsStatsBridgeImpl : SurfPaperNmsStatsBridge { override fun getPlayerStatsAsJson(player: Player): String { diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/V26_1PacketOperationImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/V26_1PacketOperationImpl.kt index 18596ab35..61a5752ae 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/V26_1PacketOperationImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/V26_1PacketOperationImpl.kt @@ -9,6 +9,7 @@ import net.minecraft.network.protocol.game.ClientboundBundlePacket import org.bukkit.entity.Player import java.util.* +@Suppress("ClassName") class V26_1PacketOperationImpl : PacketOperation { private var operation: Operation diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/V26_1SurfPaperNmsPacketBridgesImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/V26_1SurfPaperNmsPacketBridgesImpl.kt index 0382b2342..b4ad45f67 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/V26_1SurfPaperNmsPacketBridgesImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/V26_1SurfPaperNmsPacketBridgesImpl.kt @@ -4,6 +4,7 @@ import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.packets.SurfPaperNmsPacketBridges @NmsUseWithCaution +@Suppress("ClassName") class V26_1SurfPaperNmsPacketBridgesImpl : SurfPaperNmsPacketBridges { override fun createEmptyPacketOperation(): V26_1PacketOperationImpl { diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/block/V26_1SurfPaperNmsBlockPacketsImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/block/V26_1SurfPaperNmsBlockPacketsImpl.kt index e36db8fd1..0b0c8f3b0 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/block/V26_1SurfPaperNmsBlockPacketsImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/block/V26_1SurfPaperNmsBlockPacketsImpl.kt @@ -11,6 +11,7 @@ import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket import org.bukkit.block.data.BlockData @NmsUseWithCaution +@Suppress("ClassName") class V26_1SurfPaperNmsBlockPacketsImpl : SurfPaperNmsBlockPackets { override fun updateBlockData(position: BlockPosition, blockData: BlockData) = diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/entity/V26_1SurfPaperNmsSpawnPacketsImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/entity/V26_1SurfPaperNmsSpawnPacketsImpl.kt index fe2491b85..b555a7ed5 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/entity/V26_1SurfPaperNmsSpawnPacketsImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/entity/V26_1SurfPaperNmsSpawnPacketsImpl.kt @@ -27,7 +27,7 @@ import kotlin.experimental.and import kotlin.experimental.inv import kotlin.experimental.or -@Suppress("UnstableApiUsage") +@Suppress("UnstableApiUsage", "ClassName") @NmsUseWithCaution class V26_1SurfPaperNmsSpawnPacketsImpl : SurfPaperNmsSpawnPackets { private val log = logger() diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerChatPacketsImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerChatPacketsImpl.kt index 5fbfe4a2a..b26d9870f 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerChatPacketsImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerChatPacketsImpl.kt @@ -19,6 +19,7 @@ import java.util.* import net.minecraft.network.chat.MessageSignature as NmsMessageSignature @NmsUseWithCaution +@Suppress("ClassName") class V26_1SurfPaperNmsPlayerChatPacketsImpl : SurfPaperNmsPlayerChatPackets { override fun sendPlayerChatMessagePacket( senderUuid: UUID, diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerPacketsImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerPacketsImpl.kt index 5abfb7fce..c46222214 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerPacketsImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerPacketsImpl.kt @@ -16,6 +16,7 @@ import org.bukkit.event.inventory.InventoryType import org.bukkit.inventory.ItemStack @NmsUseWithCaution +@Suppress("ClassName") class V26_1SurfPaperNmsPlayerPacketsImpl : SurfPaperNmsPlayerPackets { override fun openSignEditor( diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerToastPacketsImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerToastPacketsImpl.kt index 97f6e1d7d..cc969ea12 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerToastPacketsImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/packets/player/V26_1SurfPaperNmsPlayerToastPacketsImpl.kt @@ -15,6 +15,7 @@ import java.util.* @NmsUseWithCaution +@Suppress("ClassName") class V26_1SurfPaperNmsPlayerToastPacketsImpl : SurfPaperNmsPlayerToastPackets { override fun showToast(toast: Toast) = V26_1PacketOperationImpl.complex { _, packets -> val id = Identifier.fromNamespaceAndPath("surfapi", "toast_${UUID.randomUUID()}") diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1GlowingLifecycleHandler.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1GlowingLifecycleHandler.kt index dd4e4cea2..703c314d3 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1GlowingLifecycleHandler.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1GlowingLifecycleHandler.kt @@ -9,6 +9,7 @@ import org.bukkit.World import org.bukkit.entity.Player @NmsUseWithCaution +@Suppress("ClassName") class V26_1GlowingLifecycleHandler : GlowingLifecycleHandler { override fun removeAllGlowingOnQuit(player: Player) { V26_1SurfGlowingApiImpl.removeAllGlowingOnQuit(player) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt index 0ffb35033..07c3fbf47 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt @@ -24,6 +24,7 @@ import java.util.* import java.util.concurrent.ConcurrentHashMap @NmsUseWithCaution +@Suppress("ClassName") object V26_1SurfGlowingApiImpl : SurfGlowingApi { private val entityPlayerData = ConcurrentHashMap() private val blockPlayerData = ConcurrentHashMap() diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1TeamData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1TeamData.kt index 071a53285..2d98ff548 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1TeamData.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1TeamData.kt @@ -8,6 +8,7 @@ import java.util.* import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.atomic.AtomicInteger +@Suppress("ClassName") class V26_1TeamData(color: ChatFormatting) { private val scoreboard = Scoreboard() val teamId = "glow-${uid()}${color.char}" diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityGlowingData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityGlowingData.kt index 8eb57d159..37cfa5348 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityGlowingData.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityGlowingData.kt @@ -11,6 +11,7 @@ import glm_.or import net.minecraft.ChatFormatting @NmsUseWithCaution +@Suppress("ClassName") data class EntityGlowingData( val playerData: EntityPlayerData, val entityId: Int, diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityPlayerData.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityPlayerData.kt index 652f71426..e1578d04e 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityPlayerData.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/entity/EntityPlayerData.kt @@ -5,6 +5,7 @@ import java.util.* import java.util.concurrent.ConcurrentHashMap @NmsUseWithCaution +@Suppress("ClassName") data class EntityPlayerData(val uuid: UUID) { val entities = ConcurrentHashMap() } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/V26_1NmsPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/V26_1NmsPacketImpl.kt index 0e9f028e4..dad8fafdd 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/V26_1NmsPacketImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/V26_1NmsPacketImpl.kt @@ -6,6 +6,7 @@ import net.minecraft.network.PacketListener import net.minecraft.network.protocol.Packet @NmsUseWithCaution +@Suppress("ClassName") abstract class V26_1NmsPacketImpl, Listener : PacketListener>(var nmsPacket: Nms) : NmsPacket { val nmsClass = nmsPacket.javaClass diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/V26_1PacketRegistry.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/V26_1PacketRegistry.kt index 00e8fac6c..2ddace3bb 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/V26_1PacketRegistry.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/V26_1PacketRegistry.kt @@ -22,6 +22,7 @@ import net.minecraft.network.protocol.game.ServerboundSignUpdatePacket import kotlin.reflect.KClass @OptIn(NmsUseWithCaution::class) +@Suppress("ClassName") object V26_1PacketRegistry { private typealias PacketMap = Object2ObjectOpenHashMap>, F> diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1ClientboundDisconnectPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1ClientboundDisconnectPacketImpl.kt index 450d88c84..201fc9214 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1ClientboundDisconnectPacketImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1ClientboundDisconnectPacketImpl.kt @@ -7,6 +7,7 @@ import net.minecraft.network.protocol.common.ClientCommonPacketListener import net.minecraft.network.protocol.common.ClientboundDisconnectPacket @NmsUseWithCaution +@Suppress("ClassName") class V26_1ClientboundDisconnectPacketImpl(nmsPacket: ClientboundDisconnectPacket) : V26_1NmsClientboundPacketImpl(nmsPacket), DisconnectPacket { diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1ClientboundSystemChatPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1ClientboundSystemChatPacketImpl.kt index 1581c0f26..edcf03ff4 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1ClientboundSystemChatPacketImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1ClientboundSystemChatPacketImpl.kt @@ -8,6 +8,7 @@ import net.minecraft.network.protocol.game.ClientGamePacketListener import net.minecraft.network.protocol.game.ClientboundSystemChatPacket @NmsUseWithCaution +@Suppress("ClassName") class V26_1ClientboundSystemChatPacketImpl(nmsPacket: ClientboundSystemChatPacket) : V26_1NmsClientboundPacketImpl(nmsPacket), SystemChatPacket { diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1NmsClientboundPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1NmsClientboundPacketImpl.kt index 9871fb6b3..ea1dd3f93 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1NmsClientboundPacketImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/clientbound/V26_1NmsClientboundPacketImpl.kt @@ -7,6 +7,7 @@ import net.minecraft.network.protocol.Packet import net.minecraft.network.protocol.common.ClientCommonPacketListener @NmsUseWithCaution +@Suppress("ClassName") abstract class V26_1NmsClientboundPacketImpl, Listener : ClientCommonPacketListener>( nmsPacket: Nms, ) : NmsClientboundPacket, V26_1NmsPacketImpl(nmsPacket) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1CommandSuggestionPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1CommandSuggestionPacketImpl.kt index 65c3c1e9f..101bc0e51 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1CommandSuggestionPacketImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1CommandSuggestionPacketImpl.kt @@ -5,6 +5,7 @@ import dev.slne.surf.api.paper.nms.listener.packets.serverbound.CommandSuggestio import net.minecraft.network.protocol.game.ServerboundCommandSuggestionPacket @NmsUseWithCaution +@Suppress("ClassName") class V26_1CommandSuggestionPacketImpl(nmsPacket: ServerboundCommandSuggestionPacket) : V26_1NmsServerboundPacketImpl(nmsPacket), CommandSuggestionPacket { diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1NmsServerboundPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1NmsServerboundPacketImpl.kt index ba63b29f5..50a53f218 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1NmsServerboundPacketImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1NmsServerboundPacketImpl.kt @@ -6,5 +6,6 @@ import net.minecraft.network.protocol.Packet import net.minecraft.network.protocol.common.ServerCommonPacketListener @NmsUseWithCaution +@Suppress("ClassName") abstract class V26_1NmsServerboundPacketImpl>(nmsPacket: Nms) : V26_1NmsPacketImpl(nmsPacket) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1RenameItemPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1RenameItemPacketImpl.kt index 9638ad25f..f607aebef 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1RenameItemPacketImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1RenameItemPacketImpl.kt @@ -5,6 +5,7 @@ import dev.slne.surf.api.paper.nms.listener.packets.serverbound.RenameItemPacket import net.minecraft.network.protocol.game.ServerboundRenameItemPacket @NmsUseWithCaution +@Suppress("ClassName") class V26_1RenameItemPacketImpl(nmsPacket: ServerboundRenameItemPacket) : V26_1NmsServerboundPacketImpl(nmsPacket), RenameItemPacket { override val newName: String get() = nmsPacket.name diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1ServerboundCustomPayloadPacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1ServerboundCustomPayloadPacketImpl.kt index d71c7efbe..acc03a7e8 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1ServerboundCustomPayloadPacketImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1ServerboundCustomPayloadPacketImpl.kt @@ -9,6 +9,7 @@ import net.minecraft.network.protocol.common.custom.DiscardedPayload import dev.slne.surf.api.paper.nms.listener.packets.serverbound.ServerboundCustomPayloadPacket.Payload as ApiPayload @NmsUseWithCaution +@Suppress("ClassName") class V26_1ServerboundCustomPayloadPacketImpl( nmsPacket: ServerboundCustomPayloadPacket ) : V26_1NmsServerboundPacketImpl(nmsPacket), diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1SignUpdatePacketImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1SignUpdatePacketImpl.kt index 782ccfd26..1c8b603f7 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1SignUpdatePacketImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/listener/packets/serverbound/V26_1SignUpdatePacketImpl.kt @@ -6,6 +6,7 @@ import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toBukkit import net.minecraft.network.protocol.game.ServerboundSignUpdatePacket @NmsUseWithCaution +@Suppress("ClassName") class V26_1SignUpdatePacketImpl(nmsPacket: ServerboundSignUpdatePacket) : V26_1NmsServerboundPacketImpl(nmsPacket), SignUpdatePacket { override val position get() = nmsPacket.pos.toBukkit() diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1GlowingPacketListener.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1GlowingPacketListener.kt index 9a43863f8..3e0fafef1 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1GlowingPacketListener.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1GlowingPacketListener.kt @@ -18,6 +18,7 @@ import org.bukkit.entity.Player import kotlin.time.Duration.Companion.seconds @OptIn(NmsUseWithCaution::class) +@Suppress("ClassName") object V26_1GlowingPacketListener : PacketListener { val ignoreCache = Caffeine.newBuilder() diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/lore/V26_1PacketLoreListener.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/lore/V26_1PacketLoreListener.kt index d0211e19b..ef14bab69 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/lore/V26_1PacketLoreListener.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/lore/V26_1PacketLoreListener.kt @@ -28,6 +28,7 @@ import net.minecraft.network.chat.Component as MinecraftComponent * handling the modification of lore on item stacks in packet events. */ @OptIn(NmsUseWithCaution::class) +@Suppress("ClassName") object V26_1PacketLoreListener : PacketListener { private val globalHandlersByPlugin = Object2ObjectLinkedOpenHashMap>() diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/lore/V26_1PacketLoreRegistry.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/lore/V26_1PacketLoreRegistry.kt index 1f94c23d2..174adba35 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/lore/V26_1PacketLoreRegistry.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/lore/V26_1PacketLoreRegistry.kt @@ -5,6 +5,7 @@ import dev.slne.surf.api.paper.packet.lore.SurfPaperPacketLoreHandler import org.bukkit.NamespacedKey import org.bukkit.plugin.Plugin +@Suppress("ClassName") class V26_1PacketLoreRegistry : PacketLoreRegistry { override fun register(plugin: Plugin, identifier: NamespacedKey, listener: SurfPaperPacketLoreHandler) { V26_1PacketLoreListener.register(plugin, identifier, listener) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1EntityProxy.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1EntityProxy.kt index 8dff2b153..d71202c80 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1EntityProxy.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1EntityProxy.kt @@ -7,6 +7,7 @@ import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies import xyz.jpenilla.reflectionremapper.proxy.annotation.Static @Proxies(Entity::class) +@Suppress("ClassName") interface V26_1EntityProxy { @FieldGetter("FLAG_GLOWING") diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ItemProxy.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ItemProxy.kt index f8d3e202a..8d6349e96 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ItemProxy.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ItemProxy.kt @@ -6,6 +6,7 @@ import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldSetter import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies @Proxies(Item::class) +@Suppress("ClassName") interface V26_1ItemProxy { @FieldSetter("components") fun setComponents(item: Item, components: DataComponentMap) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1Reflection.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1Reflection.kt index fa245fa3e..bc62d38b4 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1Reflection.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1Reflection.kt @@ -6,6 +6,7 @@ import dev.slne.surf.api.paper.util.reflectionProxy import xyz.jpenilla.reflectionremapper.ReflectionRemapper import xyz.jpenilla.reflectionremapper.proxy.ReflectionProxyFactory +@Suppress("ClassName") object V26_1Reflection { lateinit var SERVER_STATS_COUNTER_PROXY: V26_1ServerStatsCounterProxy private set diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ServerConnectionListenerProxy.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ServerConnectionListenerProxy.kt index aa667e46c..a2ab7a92f 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ServerConnectionListenerProxy.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ServerConnectionListenerProxy.kt @@ -6,6 +6,7 @@ import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldGetter import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies @Proxies(ServerConnectionListener::class) +@Suppress("ClassName") interface V26_1ServerConnectionListenerProxy { @FieldGetter("channels") fun getChannels(instance: ServerConnectionListener): List diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ServerStatsCounterProxy.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ServerStatsCounterProxy.kt index 991e4e692..28f64682a 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ServerStatsCounterProxy.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1ServerStatsCounterProxy.kt @@ -9,6 +9,7 @@ import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies import xyz.jpenilla.reflectionremapper.proxy.annotation.Static @Proxies(ServerStatsCounter::class) +@Suppress("ClassName") interface V26_1ServerStatsCounterProxy { @MethodName("toJson") diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1VanillaArgumentProviderImplProxy.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1VanillaArgumentProviderImplProxy.kt index 40258532f..802b7f9f8 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1VanillaArgumentProviderImplProxy.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1VanillaArgumentProviderImplProxy.kt @@ -7,6 +7,7 @@ import dev.slne.surf.api.core.reflection.SurfProxy import io.papermc.paper.command.brigadier.argument.VanillaArgumentProviderImpl @SurfProxy(VanillaArgumentProviderImpl::class) +@Suppress("ClassName") interface V26_1VanillaArgumentProviderImplProxy { @Name("wrap") diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1VanillaArgumentProviderProxy.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1VanillaArgumentProviderProxy.kt index e30dee3c9..2a7ed7d0e 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1VanillaArgumentProviderProxy.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/reflection/V26_1VanillaArgumentProviderProxy.kt @@ -4,8 +4,8 @@ import dev.slne.surf.api.core.reflection.Name import dev.slne.surf.api.core.reflection.Static import dev.slne.surf.api.core.reflection.SurfProxy - @SurfProxy(qualifiedName = "io.papermc.paper.command.brigadier.argument.VanillaArgumentProvider") +@Suppress("ClassName") interface V26_1VanillaArgumentProviderProxy { @Static diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/region/V26_1TickThreadGuard.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/region/V26_1TickThreadGuard.kt index bbf42b7b1..5cf29bbfd 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/region/V26_1TickThreadGuard.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/region/V26_1TickThreadGuard.kt @@ -12,7 +12,7 @@ import org.bukkit.World import org.bukkit.entity.Entity import org.bukkit.util.BoundingBox -@Suppress("UnstableApiUsage") +@Suppress("UnstableApiUsage", "ClassName") class V26_1TickThreadGuard : TickThreadGuard { override fun ensureTickThread(world: World, pos: Position, reason: String) { diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider deleted file mode 100644 index b5e249f89..000000000 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/resources/META-INF/services/dev.slne.surf.api.paper.nms.common.NmsProvider +++ /dev/null @@ -1 +0,0 @@ -dev.slne.surf.api.paper.server.nms.v26_1.V26_1NmsProvider diff --git a/surf-api-paper/surf-api-paper-server/build.gradle.kts b/surf-api-paper/surf-api-paper-server/build.gradle.kts index f00db308a..b9adbf5e1 100644 --- a/surf-api-paper/surf-api-paper-server/build.gradle.kts +++ b/surf-api-paper/surf-api-paper-server/build.gradle.kts @@ -97,6 +97,7 @@ paper { tasks { shadowJar { + mergeServiceFiles() val relocationPrefix: String by project relocate("me.devnatan.inventoryframework", "$relocationPrefix.devnatan.inventoryframework") } diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/PaperInstance.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/PaperInstance.kt index cd22cce88..856b2f02d 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/PaperInstance.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/PaperInstance.kt @@ -2,6 +2,7 @@ package dev.slne.surf.api.paper.server import dev.slne.surf.api.core.server.CoreInstance import dev.slne.surf.api.paper.SurfApiPaper +import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.common.NmsProvider import dev.slne.surf.api.paper.server.impl.SurfApiPaperImpl import dev.slne.surf.api.paper.server.inventory.framework.InventoryLoader @@ -9,6 +10,7 @@ import dev.slne.surf.api.paper.server.listener.ListenerManager import dev.slne.surf.api.paper.server.packet.PacketApiLoader import org.bukkit.Bukkit +@OptIn(NmsUseWithCaution::class) object PaperInstance : CoreInstance() { override suspend fun onLoad() { diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/GlowingListener.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/GlowingListener.kt index 6df1adfe9..137947ccc 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/GlowingListener.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/glow/GlowingListener.kt @@ -1,5 +1,6 @@ package dev.slne.surf.api.paper.server.impl.glow +import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.common.GlowingLifecycleHandler import dev.slne.surf.api.paper.nms.common.NmsProvider import io.papermc.paper.event.packet.PlayerChunkLoadEvent @@ -7,6 +8,7 @@ import org.bukkit.event.EventHandler import org.bukkit.event.Listener import org.bukkit.event.player.PlayerQuitEvent +@OptIn(NmsUseWithCaution::class) object GlowingListener : Listener { private val glowingLifecycleHandler: GlowingLifecycleHandler by lazy { NmsProvider.current.createGlowingLifecycleHandler() diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/SurfPaperNmsBridgeImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/SurfPaperNmsBridgeImpl.kt deleted file mode 100644 index 12ae2c753..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/SurfPaperNmsBridgeImpl.kt +++ /dev/null @@ -1,134 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms - -import com.google.auto.service.AutoService -import com.google.common.flogger.StackSize -import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader -import dev.slne.surf.api.core.util.logger -import dev.slne.surf.api.paper.api.nms.listener.NmsClientboundPacketListener -import dev.slne.surf.api.paper.api.nms.listener.NmsServerboundPacketListener -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge -import dev.slne.surf.api.paper.nms.listener.packets.clientbound.NmsClientboundPacket -import dev.slne.surf.api.paper.nms.listener.packets.serverbound.NmsServerboundPacket -import dev.slne.surf.api.paper.packet.listener.listener.PacketListenerResult -import org.bukkit.entity.Player -import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.CopyOnWriteArraySet - -@AutoService(SurfPaperNmsBridge::class) -@NmsUseWithCaution -class SurfPaperNmsBridgeImpl : SurfPaperNmsBridge { - private val log = logger() - - private val serverboundPacketListeners = - ConcurrentHashMap, CopyOnWriteArraySet>>() - private val clientboundPacketListeners = - ConcurrentHashMap, CopyOnWriteArraySet>>() - - init { - checkInstantiationByServiceLoader() - } - - override fun registerServerboundPacketListener(listener: NmsServerboundPacketListener<*>) { - val packetClass = listener.packetClass - val added = - serverboundPacketListeners.computeIfAbsent(packetClass) { CopyOnWriteArraySet() } - .add(listener) - - if (!added) { - log.atWarning() - .withStackTrace(StackSize.MEDIUM) - .log("Serverbound packet listener $listener is already registered") - } - } - - override fun unregisterServerboundPacketListener(listener: NmsServerboundPacketListener<*>) { - val removed = serverboundPacketListeners[listener.packetClass]?.remove(listener) == true - - if (!removed) { - log.atWarning() - .withStackTrace(StackSize.MEDIUM) - .log("Serverbound packet listener $listener is not registered") - } - } - - override fun registerClientboundPacketListener(listener: NmsClientboundPacketListener<*>) { - val packetClass = listener.packetClass - val added = - clientboundPacketListeners.computeIfAbsent(packetClass) { CopyOnWriteArraySet() } - .add(listener) - - if (!added) { - log.atWarning() - .withStackTrace(StackSize.MEDIUM) - .log("Clientbound packet listener $listener is already registered") - } - } - - override fun unregisterClientboundPacketListener(listener: NmsClientboundPacketListener<*>) { - val removed = clientboundPacketListeners[listener.packetClass]?.remove(listener) == true - - if (!removed) { - log.atWarning() - .withStackTrace(StackSize.MEDIUM) - .log("Clientbound packet listener $listener is not registered") - } - } - - @Suppress("UNCHECKED_CAST") - fun handleServerboundPacket( - packet: Packet, - player: Player?, - ): Packet? { - val clazz = packet.packetClass - val listener = serverboundPacketListeners[clazz] ?: return packet - - var cancel = false - for (listener in listener) { - listener as NmsServerboundPacketListener - val result = try { - listener.handleEarlyServerboundPacket(packet, player) - } catch (e: Throwable) { - log.atSevere() - .withCause(e) - .log("Failed to handle serverbound packet $clazz for listener $listener") - PacketListenerResult.CONTINUE - } - - if (result == PacketListenerResult.CANCEL) { - cancel = true - } - } - - return if (cancel) null else packet - } - - @Suppress("UNCHECKED_CAST") - fun handleClientboundPacket( - packet: Packet, - player: Player?, - ): Packet? { - val listeners = clientboundPacketListeners[packet.packetClass] ?: return packet - - if (listeners.isEmpty()) return packet - - var cancel = false - for (listener in listeners) { - listener as NmsClientboundPacketListener - val result = try { - listener.handleEarlyClientboundPacket(packet, player) - } catch (e: Throwable) { - log.atSevere() - .withCause(e) - .log("Failed to handle clientbound packet ${packet.packetClass} for listener $listener") - PacketListenerResult.CONTINUE - } - - if (result == PacketListenerResult.CANCEL) { - cancel = true - } - } - - return if (cancel) null else packet - } -} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsCommandArgumentTypesBridgeImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsCommandArgumentTypesBridgeImpl.kt deleted file mode 100644 index da08bdcbe..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsCommandArgumentTypesBridgeImpl.kt +++ /dev/null @@ -1,109 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.bridges - -import com.mojang.brigadier.arguments.ArgumentType -import com.mojang.brigadier.context.CommandContext -import com.mojang.brigadier.exceptions.CommandSyntaxException -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsCommandArgumentTypesBridge -import dev.slne.surf.api.paper.server.nms.AdventureNBT -import dev.slne.surf.api.paper.server.reflection.Reflection -import net.bytebuddy.ByteBuddy -import net.bytebuddy.dynamic.loading.ClassLoadingStrategy -import net.bytebuddy.dynamic.scaffold.TypeValidation -import net.bytebuddy.implementation.InvocationHandlerAdapter -import net.bytebuddy.implementation.bind.annotation.RuntimeType -import net.bytebuddy.matcher.ElementMatchers -import net.kyori.adventure.nbt.CompoundBinaryTag -import net.minecraft.commands.arguments.CompoundTagArgument -import java.lang.reflect.InvocationHandler -import java.util.concurrent.ConcurrentHashMap - -@NmsUseWithCaution -class SurfPaperNmsCommandArgumentTypesBridgeImpl : SurfPaperNmsCommandArgumentTypesBridge { - init { - } - - override fun compoundTag(): ArgumentType<*> { - return CompoundTagArgument.compoundTag() - } - - override fun getCompoundTag(ctx: CommandContext<*>, key: String): CompoundBinaryTag { - val nms = CompoundTagArgument.getCompoundTag(ctx, key) - return AdventureNBT.fromNms(nms) - } - - @Suppress("UNCHECKED_CAST") - private fun wrap( - base: ArgumentType, - converter: OpenedResultConverter - ): ArgumentType { - val wrappedConverter = OpenedResultConverterImpl.of(converter) - val wrapped = Reflection.VANILLA_ARGUMENT_PROVIDER_IMPL_PROXY.wrap( - Reflection.VANILLA_ARGUMENT_PROVIDER_PROXY.provider(), - base, - wrappedConverter - ) as ArgumentType - - return wrapped - } - - - fun interface OpenedResultConverter { - @Throws(CommandSyntaxException::class) - fun convert(type: T): R - } - - object OpenedResultConverterImpl { - private val converterCache = ConcurrentHashMap() - - @Suppress("UNCHECKED_CAST") - fun of(converter: OpenedResultConverter): Any { - val cacheKey = "${converter.javaClass.name}_${System.identityHashCode(converter)}" - - return converterCache.computeIfAbsent(cacheKey) { - createConverter(converter) - } - } - - @Suppress("UNCHECKED_CAST") - private fun createConverter(converter: OpenedResultConverter): Any { - val resultConverterInterface = Class.forName( - "io.papermc.paper.command.brigadier.argument.VanillaArgumentProviderImpl\$ResultConverter" - ) - - val handler = InvocationHandler { _, method, args -> - when (method.name) { - "convert" -> converter.convert(args[0] as B) - else -> throw UnsupportedOperationException("Unknown method: ${method.name}") - } - } - - val dynamicType = ByteBuddy() - .with(TypeValidation.DISABLED) - .subclass(Any::class.java) - .implement(resultConverterInterface) - .name("io.papermc.paper.command.brigadier.argument.GeneratedResultConverter\$${System.nanoTime()}") - .method(ElementMatchers.any()) - .intercept(InvocationHandlerAdapter.of(handler)) - .make() - - val loadedClass = dynamicType.load( - resultConverterInterface.classLoader, - ClassLoadingStrategy.Default.INJECTION - ).loaded - - return loadedClass.getDeclaredConstructor().newInstance() - } - - - class InterceptorHolder( - private val converter: OpenedResultConverter - ) { - @RuntimeType - @Throws(Exception::class) - fun convert(@RuntimeType input: B): C { - return converter.convert(input) - } - } - } -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsCommonBridgeImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsCommonBridgeImpl.kt deleted file mode 100644 index b12d822f5..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsCommonBridgeImpl.kt +++ /dev/null @@ -1,92 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.bridges - -import dev.slne.surf.api.paper.dialog.noticeDialogWithBuilder -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsCommonBridge -import dev.slne.surf.api.paper.server.nms.toNms -import dev.slne.surf.api.paper.server.nms.toNmsBlock -import dev.slne.surf.api.paper.server.nms.toNmsItem -import dev.slne.surf.api.paper.server.reflection.Reflection -import io.papermc.paper.configuration.GlobalConfiguration -import net.kyori.adventure.text.Component -import net.minecraft.network.protocol.common.ClientboundClearDialogPacket -import net.minecraft.server.MinecraftServer -import net.minecraft.world.level.block.Block -import net.minecraft.world.level.block.ComposterBlock -import org.bukkit.Bukkit -import org.bukkit.Material -import org.bukkit.block.data.BlockData -import org.bukkit.entity.Player -import java.net.InetSocketAddress - -@NmsUseWithCaution -class SurfPaperNmsCommonBridgeImpl : SurfPaperNmsCommonBridge { - init { - } - - @Suppress("DEPRECATION") - override fun nextEntityId(): Int { - return Bukkit.getUnsafe().nextEntityId() - } - - override fun getStateId(material: Material): Int { - return Block.getId(material.toNmsBlock().defaultBlockState()) - } - - override fun getStateId(blockData: BlockData): Int { - return Block.getId(blockData.toNms()) - } - - override fun generateNextInventoryId(player: Player): Int { - return player.toNms().nextContainerCounter() - } - - override fun addCompostable(material: Material, levelIncreaseChance: Float) { - require(material.isItem) { "material must be an item" } - - ComposterBlock.COMPOSTABLES.put(material.toNmsItem(), levelIncreaseChance) - } - - override fun removeCompostable(material: Material) { - require(material.isItem) { "material must be an item" } - ComposterBlock.COMPOSTABLES.removeFloat(material.toNmsItem()) - } - - override fun setVelocityEnabled(enabled: Boolean) { - GlobalConfiguration.get().proxies.velocity.enabled = enabled - } - - override fun isVelocityEnabled(): Boolean { - return GlobalConfiguration.get().proxies.velocity.enabled - } - - override fun setVelocitySecret(secret: String) { - GlobalConfiguration.get().proxies.velocity.secret = secret - } - - override fun getVelocitySecret(): String { - return GlobalConfiguration.get().proxies.velocity.secret - } - - override fun setOnlineMode(enabled: Boolean) { - MinecraftServer.getServer().setUsesAuthentication(enabled) - } - - override fun clearDialogs(player: Player, showEmptyDialogBefore: Boolean) { - if (showEmptyDialogBefore) { - player.showDialog(noticeDialogWithBuilder(Component.empty()) {}) - } - - player.toNms().connection.send(ClientboundClearDialogPacket.INSTANCE) - } - - override fun getServerIp(): InetSocketAddress { - val channels = - Reflection.SERVER_CONNECTION_LISTENER_PROXY.getChannels(MinecraftServer.getServer().connection) - val channel = - channels.firstOrNull() ?: error("No channels found in server connection listener proxy") - - return channel.channel().localAddress() as? InetSocketAddress - ?: error("Local address is not an instance of InetSocketAddress") - } -} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsEntityBridgeImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsEntityBridgeImpl.kt deleted file mode 100644 index 515f5f793..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsEntityBridgeImpl.kt +++ /dev/null @@ -1,55 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.bridges - -import ca.spottedleaf.moonrise.common.util.TickThread -import com.mojang.brigadier.exceptions.CommandSyntaxException -import dev.jorel.commandapi.exceptions.WrapperCommandSyntaxException -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsEntityBridge -import dev.slne.surf.api.paper.server.nms.AdventureNBT -import dev.slne.surf.api.paper.server.nms.toNms -import dev.slne.surf.api.paper.server.nms.toNmsHolder -import dev.slne.surf.api.paper.util.chunkX -import dev.slne.surf.api.paper.util.chunkZ -import io.papermc.paper.math.FinePosition -import net.kyori.adventure.nbt.CompoundBinaryTag -import net.minecraft.server.MinecraftServer -import net.minecraft.server.commands.SummonCommand -import org.bukkit.World -import org.bukkit.entity.EntityType - -@NmsUseWithCaution -class SurfPaperNmsEntityBridgeImpl : SurfPaperNmsEntityBridge { - init { - } - - @Suppress("UnstableApiUsage") - override fun createEntityByNbt( - world: World, - type: EntityType, - pos: FinePosition, - tag: CompoundBinaryTag - ) { - val worldNMS = world.toNms() - TickThread.ensureTickThread( - worldNMS, - pos.chunkX, - pos.chunkZ, - "Cannot create entity asynchronously" - ) - - val source = MinecraftServer.getServer().createCommandSourceStack() - .withLevel(worldNMS) - - try { - SummonCommand.createEntity( - source, - type.toNmsHolder(), - pos.toNms(), - AdventureNBT.toNms(tag), - false - ) - } catch (e: CommandSyntaxException) { - throw WrapperCommandSyntaxException(e) - } - } -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsItemBridgeImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsItemBridgeImpl.kt deleted file mode 100644 index e11608945..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsItemBridgeImpl.kt +++ /dev/null @@ -1,26 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.bridges - -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsItemBridge -import dev.slne.surf.api.paper.server.nms.nms -import net.minecraft.core.component.DataComponentMap -import net.minecraft.core.component.DataComponents -import org.bukkit.inventory.ItemType - -@NmsUseWithCaution -class SurfPaperNmsItemBridgeImpl : SurfPaperNmsItemBridge { - init { - } - - override fun setDefaultMaxStackSize(item: ItemType, maxStackSize: Int) { - require(maxStackSize in 1..100) { "Max stack size must be between 1 and 100" } - - val nmsItem = item.nms - val updatedComponents = DataComponentMap.builder() - .addAll(nmsItem.components()) - .set(DataComponents.MAX_STACK_SIZE, maxStackSize) - .build() - - nmsItem.builtInRegistryHolder().bindComponents(updatedComponents) - } -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsLootTableBridgeImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsLootTableBridgeImpl.kt deleted file mode 100644 index e9b7c526d..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsLootTableBridgeImpl.kt +++ /dev/null @@ -1,55 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.bridges - -import dev.slne.surf.api.core.util.emptyObjectList -import dev.slne.surf.api.core.util.mutableObjectListOf -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsLootTableBridge -import dev.slne.surf.api.paper.server.nms.toBukkit -import dev.slne.surf.api.paper.server.nms.toNms -import net.minecraft.server.MinecraftServer -import net.minecraft.server.level.ServerLevel -import net.minecraft.world.level.storage.loot.LootParams -import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets -import net.minecraft.world.level.storage.loot.parameters.LootContextParams -import org.bukkit.damage.DamageSource -import org.bukkit.entity.EntityType -import org.bukkit.entity.LivingEntity -import org.bukkit.inventory.ItemStack -import kotlin.jvm.optionals.getOrNull - -@NmsUseWithCaution -class SurfPaperNmsLootTableBridgeImpl : SurfPaperNmsLootTableBridge { - override fun getDifferentLootTable( - entity: LivingEntity, - damageSource: DamageSource, - replacement: EntityType, - causedByPlayer: Boolean, - ): Collection { - val lootTableKey = - replacement.toNms().defaultLootTable.getOrNull() ?: return emptyObjectList() - val lootTable = - MinecraftServer.getServer().reloadableRegistries().getLootTable(lootTableKey) - val nmsEntity = entity.toNms() - val nmsDamageSource = damageSource.toNms() - - val lootParamsBuilder = LootParams.Builder(nmsEntity.level() as ServerLevel) - .withParameter(LootContextParams.THIS_ENTITY, nmsEntity) - .withParameter(LootContextParams.ORIGIN, nmsEntity.position()) - .withParameter(LootContextParams.DAMAGE_SOURCE, nmsDamageSource) - .withOptionalParameter(LootContextParams.ATTACKING_ENTITY, nmsDamageSource.entity) - .withOptionalParameter( - LootContextParams.DIRECT_ATTACKING_ENTITY, - nmsDamageSource.directEntity - ) - - val lastHurtByPlayer = nmsEntity.getLastHurtByPlayer() - if (causedByPlayer && lastHurtByPlayer != null) { - lootParamsBuilder.withParameter(LootContextParams.LAST_DAMAGE_PLAYER, lastHurtByPlayer) - .withLuck(lastHurtByPlayer.luck) - } - - val lootParams = lootParamsBuilder.create(LootContextParamSets.ENTITY) - return lootTable.getRandomItems(lootParams, nmsEntity.lootTableSeed) - .mapTo(mutableObjectListOf()) { it.toBukkit() } - } -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsNbtBridgeImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsNbtBridgeImpl.kt deleted file mode 100644 index 469486f59..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsNbtBridgeImpl.kt +++ /dev/null @@ -1,63 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.bridges - -import dev.slne.surf.api.core.util.logger -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsNbtBridge -import dev.slne.surf.api.paper.server.nms.toBukkit -import dev.slne.surf.api.paper.server.nms.toNms -import net.minecraft.core.component.DataComponentPatch -import net.minecraft.core.component.DataComponents -import net.minecraft.nbt.CompoundTag -import net.minecraft.world.item.component.CustomData -import net.minecraft.world.item.component.TypedEntityData -import org.bukkit.entity.EntityType -import org.bukkit.inventory.ItemStack -import kotlin.jvm.optionals.getOrNull - -@NmsUseWithCaution -class SurfPaperNmsNbtBridgeImpl : SurfPaperNmsNbtBridge { - - private val log = logger() - - override fun makeItemStackEntityInvisible( - itemStack: ItemStack, - invisibleEntityType: EntityType, - ): ItemStack { - val nmsStack = itemStack.toNms() - - val nbt = CompoundTag() - nbt.putBoolean("Invisible", true) - nbt.putString("id", invisibleEntityType.key.asString()) - - val entityData = TypedEntityData.decodeEntity(nbt) - - val patch = DataComponentPatch.builder() - .set(DataComponents.ENTITY_DATA, entityData) - .build() - - nmsStack.applyComponents(patch) - - return nmsStack.toBukkit() - } - - @Suppress("OVERRIDE_DEPRECATION", "DEPRECATION") - override fun getNbtString( - itemStack: ItemStack, - key: String, - ): String { - log.atWarning() - .atMostEvery(30, java.util.concurrent.TimeUnit.SECONDS) - .log( - ("Using deprecated method getNbtString(ItemStack, String) in SurfBukkitNmsNbtBridgeImpl." - + " ItemStacks now use DataComponents and nbt keys are not used. Please update your" - + " code to use DataComponents instead.") - ) - - return itemStack.toNms().components - .getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY) - .unsafe - .getString(key) - .getOrNull() - ?: "{}" - } -} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsStatsBridgeImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsStatsBridgeImpl.kt deleted file mode 100644 index c263f7f9b..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/SurfPaperNmsStatsBridgeImpl.kt +++ /dev/null @@ -1,23 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.bridges - -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.bridges.SurfPaperNmsStatsBridge -import dev.slne.surf.api.paper.server.nms.toNms -import dev.slne.surf.api.paper.server.reflection.Reflection -import org.bukkit.entity.Player - -@NmsUseWithCaution -class SurfPaperNmsStatsBridgeImpl : SurfPaperNmsStatsBridge { - init { - } - - override fun getPlayerStatsAsJson(player: Player): String { - val gson = Reflection.SERVER_STATS_COUNTER_PROXY.getGson() - val jsonElement = Reflection.SERVER_STATS_COUNTER_PROXY.toJson(player.toNms().stats) - return gson.toJson(jsonElement) - } - - override fun savePlayerStatsToFile(player: Player) { - player.toNms().stats.save() - } -} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/PacketOperationImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/PacketOperationImpl.kt deleted file mode 100644 index 99b7afed5..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/PacketOperationImpl.kt +++ /dev/null @@ -1,115 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.bridges.packets - -import com.google.common.flogger.FluentLogger -import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation -import dev.slne.surf.api.paper.server.nms.toNms -import net.minecraft.network.protocol.Packet -import net.minecraft.network.protocol.game.ClientGamePacketListener -import net.minecraft.network.protocol.game.ClientboundBundlePacket -import org.bukkit.entity.Player -import java.util.* - -class PacketOperationImpl : PacketOperation { - private var operation: Operation - - private constructor(operation: Operation) { - this.operation = operation - } - - private constructor() { - this.operation = Operation.empty() - } - - override fun execute(player: Player) { - val connection = player.toNms().connection - val packets = operation.apply( - player, - LinkedList>() - ) - - if (packets.isEmpty()) { - return - } - - if (packets.size == 1) { - connection.send(packets.first()) - return - } - - connection.send(ClientboundBundlePacket(packets)) - } - - override fun add(operation: PacketOperation): PacketOperationImpl { - require(operation is PacketOperationImpl) { "operation must be an instance of PacketOperationImpl" } - - this.operation = this.operation.andThen(operation.operation) - return this - } - - override fun isEmpty(): Boolean { - val operation = operation - return operation is EmptyOperation && operation.empty - } - - fun interface Operation { - fun apply( - player: Player, - packets: LinkedList>, - ): LinkedList> - - fun andThen(after: Operation): Operation { - return Operation { player, packets -> - after.apply(player, apply(player, packets)) - } - } - - companion object { - fun empty() = EmptyOperation() - } - } - - class EmptyOperation : Operation { - var empty: Boolean = true - private set - - override fun apply( - player: Player, - packets: LinkedList>, - ): LinkedList> { - return packets - } - - override fun andThen(after: Operation): Operation { - empty = false - return super.andThen(after) - } - } - - companion object { - private val logger: FluentLogger = FluentLogger.forEnclosingClass() - - @JvmStatic - fun empty(): PacketOperationImpl { - return PacketOperationImpl() - } - - @JvmStatic - fun complex(operation: Operation): PacketOperationImpl { - return PacketOperationImpl(operation) - } - - fun simple(packetSupplier: (Player) -> Packet): PacketOperationImpl { - return PacketOperationImpl { player, packets -> - packets.add(packetSupplier(player)) - packets - } - } - - fun task(task: (Player) -> Unit): PacketOperationImpl { - return PacketOperationImpl { player, packets -> - task(player) - packets - } - } - } -} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/SurfPaperNmsPacketBridgesImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/SurfPaperNmsPacketBridgesImpl.kt deleted file mode 100644 index cf399fe2e..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/SurfPaperNmsPacketBridgesImpl.kt +++ /dev/null @@ -1,14 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.bridges.packets - -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.bridges.packets.SurfPaperNmsPacketBridges - -@NmsUseWithCaution -class SurfPaperNmsPacketBridgesImpl : SurfPaperNmsPacketBridges { - init { - } - - override fun createEmptyPacketOperation(): PacketOperationImpl { - return PacketOperationImpl.empty() - } -} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/block/SurfPaperNmsBlockPacketsImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/block/SurfPaperNmsBlockPacketsImpl.kt deleted file mode 100644 index c928aa031..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/block/SurfPaperNmsBlockPacketsImpl.kt +++ /dev/null @@ -1,34 +0,0 @@ -@file:Suppress("UnstableApiUsage") - -package dev.slne.surf.api.paper.server.impl.nms.bridges.packets.block - -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.bridges.packets.block.SurfPaperNmsBlockPackets -import dev.slne.surf.api.paper.server.impl.nms.bridges.packets.PacketOperationImpl -import dev.slne.surf.api.paper.server.nms.toNms -import io.papermc.paper.math.BlockPosition -import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket -import org.bukkit.block.data.BlockData - -@NmsUseWithCaution -class SurfPaperNmsBlockPacketsImpl : SurfPaperNmsBlockPackets { - init { - } - - override fun updateBlockData(position: BlockPosition, blockData: BlockData) = - PacketOperationImpl.simple { - ClientboundBlockUpdatePacket( - position.toNms(), - blockData.toNms() - ) - } - - - override fun resetBlock(position: BlockPosition) = PacketOperationImpl.simple { - ClientboundBlockUpdatePacket( - it.toNms().level(), - position.toNms() - ) - } -} - diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/entity/SurfPaperNmsSpawnPacketsImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/entity/SurfPaperNmsSpawnPacketsImpl.kt deleted file mode 100644 index 8ecdd16c5..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/entity/SurfPaperNmsSpawnPacketsImpl.kt +++ /dev/null @@ -1,207 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.bridges.packets.entity - -import com.google.common.flogger.StackSize -import com.mojang.math.Transformation -import dev.slne.surf.api.core.util.logger -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.bridges.packets.entity.* -import dev.slne.surf.api.paper.server.impl.nms.bridges.packets.PacketOperationImpl -import dev.slne.surf.api.paper.server.nms.toNms -import io.papermc.paper.math.BlockPosition -import io.papermc.paper.math.FinePosition -import it.unimi.dsi.fastutil.ints.IntList -import net.minecraft.core.HolderLookup -import net.minecraft.nbt.CompoundTag -import net.minecraft.nbt.NbtOps -import net.minecraft.network.protocol.game.* -import net.minecraft.server.MinecraftServer -import net.minecraft.world.entity.Display -import net.minecraft.world.entity.Entity -import net.minecraft.world.entity.EntityType -import net.minecraft.world.entity.PositionMoveRotation -import net.minecraft.world.level.block.entity.BlockEntityType -import net.minecraft.world.level.block.entity.SignText -import net.minecraft.world.phys.Vec3 -import org.bukkit.entity.TextDisplay.TextAlignment -import kotlin.experimental.and -import kotlin.experimental.inv -import kotlin.experimental.or - -@Suppress("UnstableApiUsage") -@NmsUseWithCaution -class SurfPaperNmsSpawnPacketsImpl : SurfPaperNmsSpawnPackets { - private val log = logger() - - override fun despawn(entityIds: IntList) = - PacketOperationImpl.simple { ClientboundRemoveEntitiesPacket(entityIds) } - - override fun despawn(vararg entityId: Int) = - PacketOperationImpl.simple { ClientboundRemoveEntitiesPacket(*entityId) } - - - override fun spawnItemDisplay( - entityId: Int, - position: FinePosition, - settings: ItemDisplaySettings, - ) = PacketOperationImpl.complex { player, packets -> - val serverPlayer = player.toNms() - val display = Display.ItemDisplay(EntityType.ITEM_DISPLAY, serverPlayer.level()).apply { - id = entityId - - setPosition(position) - applySettings(settings) - - itemStack = settings.itemStack.toNms() - itemTransform = settings.itemDisplayTransform.toNms() - } - - packets.add(ClientboundAddEntityPacket(display, 0, display.blockPosition())) - packets.add(createSetEntityDataPacket(entityId, display)) - packets - } - - override fun spawnTextDisplay( - entityId: Int, - position: FinePosition, - settings: TextDisplaySettings, - ) = PacketOperationImpl.complex { player, packets -> - val serverPlayer = player.toNms() - val display = Display.TextDisplay(EntityType.TEXT_DISPLAY, serverPlayer.level()).apply { - id = entityId - - setPosition(position) - applySettings(settings) - - text = settings.text.toNms() - - val data = getEntityData() - data[Display.TextDisplay.DATA_LINE_WIDTH_ID] = settings.lineWidth - data[Display.TextDisplay.DATA_BACKGROUND_COLOR_ID] = settings.backgroundColor.value() - - when (settings.textAlignment) { - TextAlignment.CENTER -> { - setFlag(Display.TextDisplay.FLAG_ALIGN_LEFT, false) - setFlag(Display.TextDisplay.FLAG_ALIGN_RIGHT, false) - } - - TextAlignment.LEFT -> { - setFlag(Display.TextDisplay.FLAG_ALIGN_LEFT, true) - setFlag(Display.TextDisplay.FLAG_ALIGN_RIGHT, false) - } - - TextAlignment.RIGHT -> { - setFlag(Display.TextDisplay.FLAG_ALIGN_LEFT, false) - setFlag(Display.TextDisplay.FLAG_ALIGN_RIGHT, true) - } - } - } - - - packets.add(ClientboundAddEntityPacket(display, 0, display.blockPosition())) - packets.add(createSetEntityDataPacket(entityId, display)) - packets - } - - override fun updateSign( - entityId: Int, - position: BlockPosition, - settings: SignBlockUpdateSettings, - ) = PacketOperationImpl.complex { player, packets -> - val nbt = CompoundTag() - val registryLookup = MinecraftServer.getServer().registryAccess() - writeUpdateSignToTag(nbt, registryLookup, settings.frontText, settings.backText) - - packets.add(ClientboundBlockEntityDataPacket(position.toNms(), BlockEntityType.SIGN, nbt)) - packets - } - - override fun spawnBlockDisplay( - entityId: Int, - position: FinePosition, - settings: BlockDisplaySettings, - ) = PacketOperationImpl.complex { player, packets -> - val serverPlayer = player.toNms() - val display = Display.BlockDisplay(EntityType.BLOCK_DISPLAY, serverPlayer.level()).apply { - id = entityId - - setPosition(position) - applySettings(settings) - blockState = settings.blockData.toNms() - } - - packets.add(ClientboundAddEntityPacket(display, 0, display.blockPosition())) - packets.add(createSetEntityDataPacket(entityId, display)) - packets - } - - override fun teleport( - entityId: Int, - position: FinePosition, - yaw: Float, - pitch: Float, - deltaMovement: FinePosition?, - onGround: Boolean, - ) = PacketOperationImpl.simple { - ClientboundTeleportEntityPacket.teleport( - entityId, - PositionMoveRotation(position.toNms(), deltaMovement?.toNms() ?: Vec3.ZERO, yaw, pitch), - emptySet(), - onGround - ) - } - - private fun createSetEntityDataPacket(entityId: Int, entity: Entity) = - ClientboundSetEntityDataPacket(entityId, entity.getEntityData().packAll()) - - private fun writeUpdateSignToTag( - nbt: CompoundTag, - registryLookup: HolderLookup.Provider, - frontText: SignBlockUpdateSettings.SignText, - backText: SignBlockUpdateSettings.SignText, - ) { - writeTextToTag(nbt, registryLookup, frontText, "front_text", true) - writeTextToTag(nbt, registryLookup, backText, "back_text", false) - } - - private fun writeTextToTag( - nbt: CompoundTag, - registryLookup: HolderLookup.Provider, - text: SignBlockUpdateSettings.SignText, - tagText: String, - isFrontText: Boolean, - ) { - val nbtOps = registryLookup.createSerializationContext(NbtOps.INSTANCE) - val textTag = SignText.DIRECT_CODEC.encodeStart(nbtOps, text.toNms()) - textTag.resultOrPartial { logFailedEncodeText(it, isFrontText) } - .ifPresent { nbt.put(tagText, it) } - } - - private fun logFailedEncodeText(string: String, front: Boolean) { - log.atSevere() - .withStackTrace(StackSize.MEDIUM) - .atMostEvery(5, java.util.concurrent.TimeUnit.SECONDS) - .log("Failed to encode %s text: %s", if (front) "front" else "back", string) - } - - private fun getTransformation(settings: DisplaySettings) = Transformation( - settings.translation.toNms(), - settings.leftRotation.toNms(), - settings.scale.toNms(), - settings.rightRotation.toNms() - ) - - private fun Display.applySettings(settings: DisplaySettings) { - xRot = settings.pitch - yRot = settings.yaw - setTransformation(getTransformation(settings)) - billboardConstraints = settings.billboardConstraints.toNms() - } - - private fun Entity.setPosition(position: FinePosition) { - setPosRaw(position.x(), position.y(), position.z()) - } - - private fun Display.TextDisplay.setFlag(flag: Byte, set: Boolean) { - flags = if (set) flags or flag else flags and flag.inv() - } -} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerChatPacketsImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerChatPacketsImpl.kt deleted file mode 100644 index 05b3dc5e6..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerChatPacketsImpl.kt +++ /dev/null @@ -1,64 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.bridges.packets.player - -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation -import dev.slne.surf.api.paper.nms.bridges.packets.player.LastSeenMessagesPacked -import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerChatPackets -import dev.slne.surf.api.paper.server.impl.nms.bridges.packets.PacketOperationImpl -import dev.slne.surf.api.paper.server.nms.toNms -import net.kyori.adventure.chat.SignedMessage -import net.kyori.adventure.text.Component -import net.minecraft.network.chat.ChatType -import net.minecraft.network.chat.FilterMask -import net.minecraft.network.chat.LastSeenMessages -import net.minecraft.network.chat.SignedMessageBody -import net.minecraft.network.protocol.game.ClientboundPlayerChatPacket -import net.minecraft.server.MinecraftServer -import java.time.Instant -import java.util.* -import net.minecraft.network.chat.MessageSignature as NmsMessageSignature - -@NmsUseWithCaution -class SurfPaperNmsPlayerChatPacketsImpl : SurfPaperNmsPlayerChatPackets { - override fun sendPlayerChatMessagePacket( - senderUuid: UUID, - senderDisplayName: Component, - globalIndex: Int, - index: Int, - signature: SignedMessage.Signature?, - salt: Long, - timestamp: Instant, - content: String, - unsignedContent: Component?, - lastSeen: LastSeenMessagesPacked, - ): PacketOperation = PacketOperationImpl.simple { player -> - val messageSignature = signature?.let { NmsMessageSignature(it.bytes()) } - val signedBody = SignedMessageBody.Packed(content, timestamp, salt, lastSeen.toNms()) - - ClientboundPlayerChatPacket( - globalIndex, - senderUuid, - index, - messageSignature, - signedBody, - unsignedContent?.toNms(), - FilterMask.PASS_THROUGH, - ChatType.bind( - ChatType.CHAT, - MinecraftServer.getServer().registryAccess(), - senderDisplayName.toNms() - ) - ) - } - - private fun LastSeenMessagesPacked.toNms(): LastSeenMessages.Packed { - val list = mutableListOf() - - for ((id, signature) in this) { - val nmsSignature = signature?.let { NmsMessageSignature(it.bytes()) } - list.add(NmsMessageSignature.Packed(id, nmsSignature)) - } - - return LastSeenMessages.Packed(list) - } -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerPacketsImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerPacketsImpl.kt deleted file mode 100644 index d9d775760..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerPacketsImpl.kt +++ /dev/null @@ -1,56 +0,0 @@ -@file:Suppress("UnstableApiUsage") - -package dev.slne.surf.api.paper.server.impl.nms.bridges.packets.player - -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerPackets -import dev.slne.surf.api.paper.server.impl.nms.bridges.packets.PacketOperationImpl -import dev.slne.surf.api.paper.server.nms.toNms -import io.papermc.paper.math.BlockPosition -import net.kyori.adventure.text.Component -import net.minecraft.network.protocol.game.ClientboundContainerClosePacket -import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket -import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket -import net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket -import org.bukkit.event.inventory.InventoryType -import org.bukkit.inventory.ItemStack - -@NmsUseWithCaution -class SurfPaperNmsPlayerPacketsImpl : SurfPaperNmsPlayerPackets { - init { - } - - override fun openSignEditor( - position: BlockPosition, - frontSide: Boolean, - ) = PacketOperationImpl.simple { ClientboundOpenSignEditorPacket(position.toNms(), frontSide) } - - override fun openInventory( - syncId: Int, - type: InventoryType, - title: Component, - ) = PacketOperationImpl.simple { - ClientboundOpenScreenPacket( - syncId, - type.toNms(), - title.toNms() - ) - } - - override fun setInventorySlot( - syncId: Int, - revision: Int, - slot: Int, - item: ItemStack, - ) = PacketOperationImpl.simple { - ClientboundContainerSetSlotPacket( - syncId, - revision, - slot, - item.toNms() - ) - } - - override fun closeInventory(syncId: Int) = - PacketOperationImpl.simple { ClientboundContainerClosePacket(syncId) } -} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerToastPacketsImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerToastPacketsImpl.kt deleted file mode 100644 index c30ec81db..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/bridges/packets/player/SurfPaperNmsPlayerToastPacketsImpl.kt +++ /dev/null @@ -1,60 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.bridges.packets.player - -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToastPackets -import dev.slne.surf.api.paper.nms.bridges.packets.player.toast.Toast -import dev.slne.surf.api.paper.server.impl.nms.bridges.packets.PacketOperationImpl -import dev.slne.surf.api.paper.server.nms.toNms -import net.minecraft.advancements.Advancement -import net.minecraft.advancements.AdvancementProgress -import net.minecraft.advancements.AdvancementRequirements -import net.minecraft.network.chat.Component -import net.minecraft.network.protocol.game.ClientboundUpdateAdvancementsPacket -import net.minecraft.resources.Identifier -import java.util.* - - -@NmsUseWithCaution -class SurfPaperNmsPlayerToastPacketsImpl : SurfPaperNmsPlayerToastPackets { - override fun showToast(toast: Toast) = PacketOperationImpl.complex { _, packets -> - val id = Identifier.fromNamespaceAndPath("surfapi", "toast_${UUID.randomUUID()}") - - packets.add(showPacket(id, toast)) - packets.add(hidePacket(id)) - - packets - } - - private fun showPacket(id: Identifier, toast: Toast) = - ClientboundUpdateAdvancementsPacket( - false, listOf(createAdvancement(id, toast)), emptySet(), mapOf( - id to AdvancementProgress().apply { - update(requirements) - grantProgress(CRITERION_ID) - }), true - ) - - private fun hidePacket(id: Identifier) = ClientboundUpdateAdvancementsPacket( - false, emptyList(), setOf(id), emptyMap(), false - ) - - private fun createAdvancement(id: Identifier, toast: Toast) = - Advancement.Builder.recipeAdvancement() - .display( - toast.icon.toNms().item, - toast.title.toNms(), - Component.empty(), - null, - toast.frame.toNms(), - true, - false, - false - ) - .requirements(requirements) - .build(id) - - companion object { - private const val CRITERION_ID = "surfapi_toast" - private val requirements by lazy { AdvancementRequirements.allOf(listOf(CRITERION_ID)) } - } -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/NmsPacketImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/NmsPacketImpl.kt deleted file mode 100644 index 94efd1670..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/NmsPacketImpl.kt +++ /dev/null @@ -1,24 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.listener.packets - -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.listener.packets.NmsPacket -import net.minecraft.network.PacketListener -import net.minecraft.network.protocol.Packet - -@NmsUseWithCaution -abstract class NmsPacketImpl, Listener : PacketListener>(var nmsPacket: Nms) : - NmsPacket { - val nmsClass = nmsPacket.javaClass - - override val packetClass = - javaClass.interfaces.find { NmsPacket::class.java.isAssignableFrom(it) } - ?: error("No packet interface found for ${javaClass.name}") - - companion object { - @JvmStatic - fun getFromApi(nmsPacket: NmsPacket): NmsPacketImpl<*, *> { - require(nmsPacket is NmsPacketImpl<*, *>) { "Invalid NmsPacket implementation: " + nmsPacket.javaClass.getName() } - return nmsPacket - } - } -} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/PacketRegistry.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/PacketRegistry.kt deleted file mode 100644 index b7fbdecf4..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/PacketRegistry.kt +++ /dev/null @@ -1,78 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.listener.packets - -import dev.slne.surf.api.core.util.mutableObject2ObjectMapOf -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.listener.packets.clientbound.NmsClientboundPacket -import dev.slne.surf.api.paper.nms.listener.packets.serverbound.NmsServerboundPacket -import dev.slne.surf.api.paper.server.impl.nms.listener.packets.clientbound.ClientboundDisconnectPacketImpl -import dev.slne.surf.api.paper.server.impl.nms.listener.packets.clientbound.ClientboundSystemChatPacketImpl -import dev.slne.surf.api.paper.server.impl.nms.listener.packets.serverbound.CommandSuggestionPacketImpl -import dev.slne.surf.api.paper.server.impl.nms.listener.packets.serverbound.RenameItemPacketImpl -import dev.slne.surf.api.paper.server.impl.nms.listener.packets.serverbound.ServerboundCustomPayloadPacketImpl -import dev.slne.surf.api.paper.server.impl.nms.listener.packets.serverbound.SignUpdatePacketImpl -import net.minecraft.network.protocol.Packet -import net.minecraft.network.protocol.common.ClientCommonPacketListener -import net.minecraft.network.protocol.common.ClientboundDisconnectPacket -import net.minecraft.network.protocol.common.ServerCommonPacketListener -import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket -import net.minecraft.network.protocol.game.ClientboundSystemChatPacket -import net.minecraft.network.protocol.game.ServerboundCommandSuggestionPacket -import net.minecraft.network.protocol.game.ServerboundRenameItemPacket -import net.minecraft.network.protocol.game.ServerboundSignUpdatePacket -import kotlin.reflect.KClass - -@OptIn(NmsUseWithCaution::class) -object PacketRegistry { - private val SERVERBOUND_PACKETS = - mutableObject2ObjectMapOf>, ServerboundPacketFactory<*, *>>() - private val CLIENTBOUND_PACKETS = - mutableObject2ObjectMapOf>, ClientboundPacketFactory<*, *>>() - - init { - // @formatter:off - // Serverbound packets - registerServerboundPacket(ServerboundSignUpdatePacket::class) { SignUpdatePacketImpl(it) } - registerServerboundPacket(ServerboundRenameItemPacket::class) { RenameItemPacketImpl(it) } - registerServerboundPacket(ServerboundCommandSuggestionPacket::class) { CommandSuggestionPacketImpl(it) } - registerServerboundPacket(ServerboundCustomPayloadPacket::class) { ServerboundCustomPayloadPacketImpl(it) } - - // Clientbound packets - registerClientboundPacket(ClientboundDisconnectPacket::class) { ClientboundDisconnectPacketImpl(it) } - registerClientboundPacket(ClientboundSystemChatPacket::class) { ClientboundSystemChatPacketImpl(it) } - // @formatter:on - } - - private fun , Api : NmsServerboundPacket> registerServerboundPacket( - nms: KClass, - factory: ServerboundPacketFactory, - ) { - SERVERBOUND_PACKETS[nms.java] = factory - } - - @Suppress("UNCHECKED_CAST") - fun > createServerboundPacketOrNull(packet: Nms): NmsServerboundPacket? { - val factory = SERVERBOUND_PACKETS[packet.javaClass] as? ServerboundPacketFactory - return factory?.create(packet) - } - - private fun , Api : NmsClientboundPacket, Listener : ClientCommonPacketListener> registerClientboundPacket( - nms: KClass, - factory: ClientboundPacketFactory, - ) { - CLIENTBOUND_PACKETS[nms.java] = factory - } - - @Suppress("UNCHECKED_CAST") - fun > createClientboundPacketOrNull(packet: Nms): NmsClientboundPacket? { - val factory = CLIENTBOUND_PACKETS[packet.javaClass] as? ClientboundPacketFactory - return factory?.create(packet) - } - - private fun interface ServerboundPacketFactory, Api : NmsServerboundPacket> { - fun create(packet: Nms): Api - } - - private fun interface ClientboundPacketFactory, Api : NmsClientboundPacket> { - fun create(packet: Nms): Api - } -} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/clientbound/ClientboundDisconnectPacketImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/clientbound/ClientboundDisconnectPacketImpl.kt deleted file mode 100644 index 8cec3344f..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/clientbound/ClientboundDisconnectPacketImpl.kt +++ /dev/null @@ -1,14 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.listener.packets.clientbound - -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.listener.packets.clientbound.DisconnectPacket -import dev.slne.surf.api.paper.server.nms.toBukkit -import net.minecraft.network.protocol.common.ClientCommonPacketListener -import net.minecraft.network.protocol.common.ClientboundDisconnectPacket - -@NmsUseWithCaution -class ClientboundDisconnectPacketImpl(nmsPacket: ClientboundDisconnectPacket) : - NmsClientboundPacketImpl(nmsPacket), - DisconnectPacket { - override val reason get() = nmsPacket.reason.toBukkit() -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/clientbound/ClientboundSystemChatPacketImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/clientbound/ClientboundSystemChatPacketImpl.kt deleted file mode 100644 index 5480b2dca..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/clientbound/ClientboundSystemChatPacketImpl.kt +++ /dev/null @@ -1,25 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.listener.packets.clientbound - -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.listener.packets.clientbound.SystemChatPacket -import dev.slne.surf.api.paper.server.nms.toBukkit -import net.kyori.adventure.text.Component -import net.minecraft.network.protocol.game.ClientGamePacketListener -import net.minecraft.network.protocol.game.ClientboundSystemChatPacket - -@NmsUseWithCaution -class ClientboundSystemChatPacketImpl(nmsPacket: ClientboundSystemChatPacket) : - NmsClientboundPacketImpl(nmsPacket), - SystemChatPacket { - override var content: Component - get() = nmsPacket.content().toBukkit() - set(value) { - nmsPacket = ClientboundSystemChatPacket(value, nmsPacket.overlay) - } - - override var overlay: Boolean - get() = nmsPacket.overlay() - set(value) { - nmsPacket = ClientboundSystemChatPacket(nmsPacket.content(), value) - } -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/clientbound/NmsClientboundPacketImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/clientbound/NmsClientboundPacketImpl.kt deleted file mode 100644 index 6ce087623..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/clientbound/NmsClientboundPacketImpl.kt +++ /dev/null @@ -1,12 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.listener.packets.clientbound - -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.listener.packets.clientbound.NmsClientboundPacket -import dev.slne.surf.api.paper.server.impl.nms.listener.packets.NmsPacketImpl -import net.minecraft.network.protocol.Packet -import net.minecraft.network.protocol.common.ClientCommonPacketListener - -@NmsUseWithCaution -abstract class NmsClientboundPacketImpl, Listener : ClientCommonPacketListener>( - nmsPacket: Nms, -) : NmsClientboundPacket, NmsPacketImpl(nmsPacket) \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/serverbound/CommandSuggestionPacketImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/serverbound/CommandSuggestionPacketImpl.kt deleted file mode 100644 index f168dc5f9..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/serverbound/CommandSuggestionPacketImpl.kt +++ /dev/null @@ -1,13 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.listener.packets.serverbound - -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.listener.packets.serverbound.CommandSuggestionPacket -import net.minecraft.network.protocol.game.ServerboundCommandSuggestionPacket - -@NmsUseWithCaution -class CommandSuggestionPacketImpl(nmsPacket: ServerboundCommandSuggestionPacket) : - NmsServerboundPacketImpl(nmsPacket), - CommandSuggestionPacket { - override val completionId get() = nmsPacket.id - override val command get() = nmsPacket.command -} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/serverbound/NmsServerboundPacketImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/serverbound/NmsServerboundPacketImpl.kt deleted file mode 100644 index 5e9dbea8f..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/serverbound/NmsServerboundPacketImpl.kt +++ /dev/null @@ -1,10 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.listener.packets.serverbound - -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.server.impl.nms.listener.packets.NmsPacketImpl -import net.minecraft.network.protocol.Packet -import net.minecraft.network.protocol.common.ServerCommonPacketListener - -@NmsUseWithCaution -abstract class NmsServerboundPacketImpl>(nmsPacket: Nms) : - NmsPacketImpl(nmsPacket) diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/serverbound/RenameItemPacketImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/serverbound/RenameItemPacketImpl.kt deleted file mode 100644 index 1ea116406..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/serverbound/RenameItemPacketImpl.kt +++ /dev/null @@ -1,11 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.listener.packets.serverbound - -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.listener.packets.serverbound.RenameItemPacket -import net.minecraft.network.protocol.game.ServerboundRenameItemPacket - -@NmsUseWithCaution -class RenameItemPacketImpl(nmsPacket: ServerboundRenameItemPacket) : - NmsServerboundPacketImpl(nmsPacket), RenameItemPacket { - override val newName: String get() = nmsPacket.name -} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/serverbound/ServerboundCustomPayloadPacketImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/serverbound/ServerboundCustomPayloadPacketImpl.kt deleted file mode 100644 index e1bb7e851..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/serverbound/ServerboundCustomPayloadPacketImpl.kt +++ /dev/null @@ -1,42 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.listener.packets.serverbound - -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import io.papermc.paper.adventure.PaperAdventure -import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket -import net.minecraft.network.protocol.common.custom.BrandPayload -import net.minecraft.network.protocol.common.custom.CustomPacketPayload -import net.minecraft.network.protocol.common.custom.DiscardedPayload -import dev.slne.surf.api.paper.nms.listener.packets.serverbound.ServerboundCustomPayloadPacket.Payload as ApiPayload - -@NmsUseWithCaution -class ServerboundCustomPayloadPacketImpl( - nmsPacket: ServerboundCustomPayloadPacket -) : NmsServerboundPacketImpl(nmsPacket), - dev.slne.surf.api.paper.nms.listener.packets.serverbound.ServerboundCustomPayloadPacket { - - override var payload: ApiPayload - get() = toApiPayload(nmsPacket.payload); - set(value) { - nmsPacket = ServerboundCustomPayloadPacket(toNmsPayload(value)) - } - - companion object { - private fun toApiPayload(nmsPayload: CustomPacketPayload): ApiPayload = when (nmsPayload) { - is BrandPayload -> ApiPayload.Brand(nmsPayload.brand) - is DiscardedPayload -> ApiPayload.Discarded( - id = PaperAdventure.asAdventure(nmsPayload.id), - data = nmsPayload.data - ) - - else -> error("Unknown CustomPacketPayload type: ${nmsPayload.type()}") - } - - private fun toNmsPayload(apiPayload: ApiPayload): CustomPacketPayload = when (apiPayload) { - is ApiPayload.Brand -> BrandPayload(apiPayload.brand) - is ApiPayload.Discarded -> DiscardedPayload( - PaperAdventure.asVanilla(apiPayload.id), - apiPayload.data - ) - } - } -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/serverbound/SignUpdatePacketImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/serverbound/SignUpdatePacketImpl.kt deleted file mode 100644 index 93abf0a2e..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/nms/listener/packets/serverbound/SignUpdatePacketImpl.kt +++ /dev/null @@ -1,19 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.nms.listener.packets.serverbound - -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.listener.packets.serverbound.SignUpdatePacket -import dev.slne.surf.api.paper.server.nms.toBukkit -import net.minecraft.network.protocol.game.ServerboundSignUpdatePacket - -@NmsUseWithCaution -class SignUpdatePacketImpl(nmsPacket: ServerboundSignUpdatePacket) : - NmsServerboundPacketImpl(nmsPacket), SignUpdatePacket { - override val position get() = nmsPacket.pos.toBukkit() - override val lines: Array get() = nmsPacket.lines - override val isFrontText get() = nmsPacket.isFrontText - - override fun getLine(line: Int): String { - require(line in 1..4) { "Line must be between 1 and 4" } - return lines[line - 1] - } -} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/packet/SurfPaperPacketApiImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/packet/SurfPaperPacketApiImpl.kt index 7df74edc4..7e0891c61 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/packet/SurfPaperPacketApiImpl.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/packet/SurfPaperPacketApiImpl.kt @@ -2,6 +2,7 @@ package dev.slne.surf.api.paper.server.impl.packet import com.google.auto.service.AutoService import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.common.NmsProvider import dev.slne.surf.api.paper.nms.common.PacketLoreRegistry import dev.slne.surf.api.paper.packet.SurfPaperPacketApi @@ -9,6 +10,7 @@ import dev.slne.surf.api.paper.packet.lore.SurfPaperPacketLoreHandler import org.bukkit.NamespacedKey import org.bukkit.plugin.Plugin +@NmsUseWithCaution @AutoService(SurfPaperPacketApi::class) class SurfPaperPacketApiImpl : SurfPaperPacketApi { private val packetLoreRegistry: PacketLoreRegistry = NmsProvider.current.createPacketLoreRegistry() diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/region/TickThreadGuardImpl.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/region/TickThreadGuardImpl.kt deleted file mode 100644 index 1c892806f..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/region/TickThreadGuardImpl.kt +++ /dev/null @@ -1,67 +0,0 @@ -package dev.slne.surf.api.paper.server.impl.region - -import ca.spottedleaf.moonrise.common.util.TickThread -import dev.slne.surf.api.paper.region.TickThreadGuard -import dev.slne.surf.api.paper.server.nms.toNms -import dev.slne.surf.api.paper.util.chunkX -import dev.slne.surf.api.paper.util.chunkZ -import io.papermc.paper.math.Position -import net.minecraft.core.BlockPos -import net.minecraft.world.phys.AABB -import org.bukkit.World -import org.bukkit.entity.Entity -import org.bukkit.util.BoundingBox - -@Suppress("UnstableApiUsage") -class TickThreadGuardImpl : TickThreadGuard { - init { - } - - override fun ensureTickThread(world: World, pos: Position, reason: String) { - TickThread.ensureTickThread(world.toNms(), pos.chunkX, pos.chunkZ, reason) - } - - override fun ensureTickThread( - world: World, - pos: Position, - blockRadius: Int, - reason: String - ) { - TickThread.ensureTickThread( - world.toNms(), - BlockPos(pos.blockX(), pos.blockY(), pos.blockZ()), - blockRadius, - reason - ) - } - - override fun ensureTickThread( - world: World, - chunkX: Int, - chunkZ: Int, - reason: String - ) { - TickThread.ensureTickThread(world.toNms(), chunkX, chunkZ, reason) - } - - override fun ensureTickThread(entity: Entity, reason: String) { - TickThread.ensureTickThread(entity.toNms(), reason) - } - - override fun ensureTickThread(world: World, box: BoundingBox, reason: String) { - TickThread.ensureTickThread( - world.toNms(), - AABB(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ), - reason - ) - } - - override fun ensureTickThread( - world: World, - blockX: Double, - blockZ: Double, - reason: String - ) { - TickThread.ensureTickThread(world.toNms(), blockX, blockZ, reason) - } -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/nms/AdventureNBT.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/nms/AdventureNBT.kt deleted file mode 100644 index 80ee2ca13..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/nms/AdventureNBT.kt +++ /dev/null @@ -1,96 +0,0 @@ -package dev.slne.surf.api.paper.server.nms - -import net.kyori.adventure.nbt.* -import net.minecraft.nbt.* - -object AdventureNBT { - fun toNms( - adventure: CompoundBinaryTag, - accounter: NbtAccounter = NbtAccounter.unlimitedHeap() - ): CompoundTag { - return CompoundTag().also { tag -> - for ((key, value) in adventure) { - tag.put(key, toNms(value, accounter)) - } - } - } - - fun toNms( - adventure: BinaryTag, - accounter: NbtAccounter = NbtAccounter.unlimitedHeap() - ): Tag { - accounter.pushDepth() - - val nmsTag = when (adventure) { - is IntBinaryTag -> IntTag.valueOf(adventure.value()) - is ByteBinaryTag -> ByteTag.valueOf(adventure.value()) - is FloatBinaryTag -> FloatTag.valueOf(adventure.value()) - is LongBinaryTag -> LongTag.valueOf(adventure.value()) - is DoubleBinaryTag -> DoubleTag.valueOf(adventure.value()) - is ShortBinaryTag -> ShortTag.valueOf(adventure.value()) - is StringBinaryTag -> StringTag.valueOf(adventure.value()) - is ByteArrayBinaryTag -> ByteArrayTag(adventure.value()) - is IntArrayBinaryTag -> IntArrayTag(adventure.value()) - is LongArrayBinaryTag -> LongArrayTag(adventure.value()) - is EndBinaryTag -> EndTag.INSTANCE - is ListBinaryTag -> if (adventure.isEmpty) { - ListTag() - } else { - val list = ListTag() - for (entry in adventure) { - val nms = toNms(entry) - list.add(nms) - } - list - } - - is CompoundBinaryTag -> { - val tag = CompoundTag() - for ((key, entry) in adventure) { - val nms = toNms(entry) - tag.put(key, nms) - } - tag - } - - else -> throw IllegalArgumentException("Unsupported tag type: ${adventure::class}") - } - - accounter.popDepth() - - return nmsTag - } - - fun fromNms(nms: CompoundTag): CompoundBinaryTag = CompoundBinaryTag.builder().also { builder -> - nms.forEach { key, tag -> builder.put(key, fromNms(tag)) } - }.build() - - fun fromNms(nms: Tag): BinaryTag = when (nms) { - is IntTag -> IntBinaryTag.intBinaryTag(nms.intValue()) - is ByteTag -> ByteBinaryTag.byteBinaryTag(nms.byteValue()) - is FloatTag -> FloatBinaryTag.floatBinaryTag(nms.floatValue()) - is LongTag -> LongBinaryTag.longBinaryTag(nms.longValue()) - is DoubleTag -> DoubleBinaryTag.doubleBinaryTag(nms.doubleValue()) - is ShortTag -> ShortBinaryTag.shortBinaryTag(nms.shortValue()) - is StringTag -> StringBinaryTag.stringBinaryTag(nms.value()) - is ByteArrayTag -> ByteArrayBinaryTag.byteArrayBinaryTag(*nms.asByteArray) - is IntArrayTag -> IntArrayBinaryTag.intArrayBinaryTag(*nms.asIntArray) - is LongArrayTag -> LongArrayBinaryTag.longArrayBinaryTag(*nms.asLongArray) - is EndTag -> EndBinaryTag.endBinaryTag() - is ListTag -> { - val tag = ListBinaryTag.heterogeneousListBinaryTag() - for (t in nms) { - tag.add(fromNms(t)) - } - tag.build() - } - - is CompoundTag -> { - val adventure = CompoundBinaryTag.builder() - nms.forEach { key, tag -> - adventure.put(key, fromNms(tag)) - } - adventure.build() - } - } -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/nms/bridge/InternalNmsBridge.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/nms/bridge/InternalNmsBridge.kt new file mode 100644 index 000000000..e86e4c52d --- /dev/null +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/nms/bridge/InternalNmsBridge.kt @@ -0,0 +1,24 @@ +package dev.slne.surf.api.paper.server.nms.bridge + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge +import dev.slne.surf.api.paper.nms.listener.packets.clientbound.NmsClientboundPacket +import dev.slne.surf.api.paper.nms.listener.packets.serverbound.NmsServerboundPacket +import org.bukkit.entity.Player + +@NmsUseWithCaution +interface InternalNmsBridge : SurfPaperNmsBridge { + fun handleServerboundPacket( + packet: Packet, + player: Player?, + ): Packet? + + fun handleClientboundPacket( + packet: Packet, + player: Player?, + ): Packet? + + companion object { + fun get() = SurfPaperNmsBridge.INSTANCE as InternalNmsBridge + } +} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/nms/nms-extensions.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/nms/nms-extensions.kt index 2c27f1a6f..f374249d7 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/nms/nms-extensions.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/nms/nms-extensions.kt @@ -3,148 +3,16 @@ package dev.slne.surf.api.paper.server.nms import dev.slne.surf.api.paper.extensions.server -import dev.slne.surf.api.paper.nms.bridges.packets.entity.SignBlockUpdateSettings -import io.papermc.paper.advancement.AdvancementDisplay -import io.papermc.paper.advancement.AdvancementDisplay.Frame.* -import io.papermc.paper.adventure.PaperAdventure -import io.papermc.paper.math.BlockPosition -import io.papermc.paper.math.FinePosition -import io.papermc.paper.math.Position -import net.minecraft.advancements.AdvancementType -import net.minecraft.core.BlockPos -import net.minecraft.core.Holder -import net.minecraft.network.chat.Component -import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerPlayer -import net.minecraft.world.entity.Display -import net.minecraft.world.inventory.MenuType -import net.minecraft.world.item.DyeColor -import net.minecraft.world.item.Item -import net.minecraft.world.item.ItemDisplayContext -import net.minecraft.world.level.block.Block -import net.minecraft.world.level.block.entity.SignText -import net.minecraft.world.phys.Vec3 -import org.bukkit.Material import org.bukkit.Server -import org.bukkit.World -import org.bukkit.block.BlockState -import org.bukkit.block.data.BlockData import org.bukkit.craftbukkit.CraftServer -import org.bukkit.craftbukkit.CraftWorld -import org.bukkit.craftbukkit.block.CraftBlockState -import org.bukkit.craftbukkit.block.data.CraftBlockData -import org.bukkit.craftbukkit.damage.CraftDamageSource -import org.bukkit.craftbukkit.entity.CraftEntity -import org.bukkit.craftbukkit.entity.CraftEntityType -import org.bukkit.craftbukkit.entity.CraftLivingEntity import org.bukkit.craftbukkit.entity.CraftPlayer -import org.bukkit.craftbukkit.inventory.CraftItemStack -import org.bukkit.craftbukkit.inventory.CraftItemType import org.bukkit.craftbukkit.util.Commodore import org.bukkit.craftbukkit.util.CraftMagicNumbers -import org.bukkit.damage.DamageSource -import org.bukkit.entity.Display.Billboard -import org.bukkit.entity.Entity -import org.bukkit.entity.EntityType -import org.bukkit.entity.ItemDisplay.ItemDisplayTransform -import org.bukkit.entity.LivingEntity import org.bukkit.entity.Player -import org.bukkit.event.inventory.InventoryType -import org.bukkit.inventory.ItemStack -import org.bukkit.inventory.ItemType -import org.spongepowered.math.imaginary.Quaternionf -import org.spongepowered.math.vector.Vector3f -import net.kyori.adventure.text.Component as AdventureComponent -import net.minecraft.world.item.ItemStack as NmsItemStack -import net.minecraft.world.level.block.state.BlockState as NmsBlockState -import org.joml.Quaternionf as NmsQuaternionf -import org.joml.Vector3f as NmsVector3f fun Player.toNms(): ServerPlayer = (this as CraftPlayer).handle -fun Material.toNmsBlock(): Block = CraftMagicNumbers.getBlock(this) -fun Material.toNmsItem(): Item = CraftMagicNumbers.getItem(this) -fun BlockData.toNms(): NmsBlockState = (this as CraftBlockData).state -fun Vector3f?.toNms(): NmsVector3f? = - if (this == null) null else NmsVector3f(this.x(), this.y(), this.z()) - -fun FinePosition.toNms() = Vec3(x(), y(), z()) -fun BlockState.toNms(): NmsBlockState = (this as CraftBlockState).handle -fun Quaternionf?.toNms(): NmsQuaternionf? = - if (this == null) null else NmsQuaternionf(x(), y(), z(), w()) - -fun Billboard.toNms(): Display.BillboardConstraints = - Display.BillboardConstraints.valueOf(this.name) - -fun ItemStack.toNms(): NmsItemStack = CraftItemStack.asNMSCopy(this) -fun ItemDisplayTransform.toNms(): ItemDisplayContext = ItemDisplayContext.BY_ID.apply(this.ordinal) -fun NmsItemStack.toBukkit(): ItemStack = CraftItemStack.asBukkitCopy(this) -val ItemType.nms: Item get() = CraftItemType.bukkitToMinecraftNew(this) -fun BlockPosition.toNms(): BlockPos = BlockPos(blockX(), blockY(), blockZ()) -fun SignBlockUpdateSettings.SignText.toNms(): SignText { - val lines = arrayOf( - line1.toNms(), - line2.toNms(), - line3.toNms(), - line4.toNms() - ) - - return SignText(lines, lines, DyeColor.BLACK, false) -} - -fun InventoryType.toNms(): MenuType<*> = when (this) { - InventoryType.ANVIL -> MenuType.ANVIL - InventoryType.BEACON -> MenuType.BEACON - InventoryType.BLAST_FURNACE -> MenuType.BLAST_FURNACE - InventoryType.BREWING -> MenuType.BREWING_STAND - InventoryType.CARTOGRAPHY -> MenuType.CARTOGRAPHY_TABLE - InventoryType.CHEST -> MenuType.GENERIC_9x6 - InventoryType.DISPENSER, InventoryType.DROPPER -> MenuType.GENERIC_3x3 - InventoryType.ENCHANTING -> MenuType.ENCHANTMENT - InventoryType.FURNACE -> MenuType.FURNACE - InventoryType.GRINDSTONE -> MenuType.GRINDSTONE - InventoryType.HOPPER -> MenuType.HOPPER - InventoryType.LECTERN -> MenuType.LECTERN - InventoryType.LOOM -> MenuType.LOOM - InventoryType.MERCHANT -> MenuType.MERCHANT - InventoryType.SHULKER_BOX -> MenuType.SHULKER_BOX - InventoryType.SMOKER -> MenuType.SMOKER - InventoryType.SMITHING -> MenuType.SMITHING - InventoryType.STONECUTTER -> MenuType.STONECUTTER - InventoryType.PLAYER -> MenuType.GENERIC_9x4 - InventoryType.CRAFTER -> MenuType.CRAFTER_3x3 - InventoryType.WORKBENCH -> MenuType.CRAFTING - InventoryType.BARREL, InventoryType.CHISELED_BOOKSHELF, InventoryType.DECORATED_POT, InventoryType.JUKEBOX, InventoryType.COMPOSTER, InventoryType.ENDER_CHEST -> MenuType.GENERIC_9x3 - InventoryType.CREATIVE, InventoryType.CRAFTING -> throw UnsupportedOperationException("Can't open a $this inventory!") - else -> throw UnsupportedOperationException("Unknown inventory type: $this") -} - -fun BlockPos.toBukkit(): BlockPosition = Position.block(x, y, z) - -fun Array.toBukkit() = this.map { it.toBukkit() } -fun AdventureComponent.toNms(): Component = PaperAdventure.asVanilla(this) -fun Component.toBukkit(): AdventureComponent = PaperAdventure.asAdventure(this) fun Server.toCraft() = this as CraftServer val craftServer: CraftServer get() = server.toCraft() val commodore: Commodore get() = CraftMagicNumbers.INSTANCE.commodore - -fun EntityType.toNms(): net.minecraft.world.entity.EntityType<*> = - CraftEntityType.bukkitToMinecraft(this) - -@Suppress("DEPRECATION") -fun EntityType.toNmsHolder() = - CraftEntityType.bukkitToMinecraftHolder(this) as Holder.Reference> - -fun World.toNms(): ServerLevel = (this as CraftWorld).handle -fun Entity.toNms(): net.minecraft.world.entity.Entity = (this as CraftEntity).handleRaw -fun LivingEntity.toNms(): net.minecraft.world.entity.LivingEntity = - (this as CraftLivingEntity).handle - -fun DamageSource.toNms(): net.minecraft.world.damagesource.DamageSource = - (this as CraftDamageSource).handle - -fun AdvancementDisplay.Frame.toNms() = when (this) { - CHALLENGE -> AdvancementType.CHALLENGE - GOAL -> AdvancementType.GOAL - TASK -> AdvancementType.TASK -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt index 9489d5b5c..b0f9cbe21 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt @@ -13,6 +13,7 @@ import dev.slne.surf.api.paper.server.packet.lore.PluginDisablePacketLoreListene import dev.slne.surf.api.paper.server.plugin import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder +@OptIn(NmsUseWithCaution::class) object PacketApiLoader { private var versionPacketListeners: List = emptyList() diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/listener/PlayerChannelInjector.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/listener/PlayerChannelInjector.kt index 00d2c28d9..842b2e80b 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/listener/PlayerChannelInjector.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/listener/PlayerChannelInjector.kt @@ -9,13 +9,10 @@ import dev.slne.surf.api.core.reflection.SurfReflection import dev.slne.surf.api.core.reflection.createProxy import dev.slne.surf.api.core.util.logger import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge -import dev.slne.surf.api.paper.nms.common.NmsPacketBridgeHandler import dev.slne.surf.api.paper.nms.common.NmsProvider -import dev.slne.surf.api.paper.nms.listener.packets.NmsPacket import dev.slne.surf.api.paper.packet.listener.SurfPaperPacketListenerApi -import dev.slne.surf.api.paper.server.impl.nms.SurfPaperNmsBridgeImpl import dev.slne.surf.api.paper.server.impl.packet.listener.SurfPaperPacketListenerApiImpl +import dev.slne.surf.api.paper.server.nms.bridge.InternalNmsBridge import dev.slne.surf.api.paper.server.nms.toNms import dev.slne.surf.api.paper.server.plugin import io.netty.channel.Channel @@ -125,11 +122,10 @@ object PlayerChannelInjector : Listener { @OptIn(NmsUseWithCaution::class) private class PacketHandler : ChannelDuplexHandler() { - private val bridge = SurfPaperNmsBridge.INSTANCE as SurfPaperNmsBridgeImpl + private val bridge = InternalNmsBridge.get() private val packetListenerApi = SurfPaperPacketListenerApi.INSTANCE as SurfPaperPacketListenerApiImpl - private val packetBridgeHandler: NmsPacketBridgeHandler = - NmsProvider.current.createPacketBridgeHandler() + private val packetBridgeHandler = NmsProvider.current.getPacketBridgeHandler() @Volatile var connection: Connection? = null diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/lore/PluginDisablePacketLoreListener.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/lore/PluginDisablePacketLoreListener.kt index 888069bae..445cc7e02 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/lore/PluginDisablePacketLoreListener.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/lore/PluginDisablePacketLoreListener.kt @@ -1,10 +1,12 @@ package dev.slne.surf.api.paper.server.packet.lore +import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.common.NmsProvider import org.bukkit.event.EventHandler import org.bukkit.event.Listener import org.bukkit.event.server.PluginDisableEvent +@NmsUseWithCaution object PluginDisablePacketLoreListener : Listener { private val packetLoreRegistry by lazy { NmsProvider.current.createPacketLoreRegistry() } diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfGlowingApiProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfGlowingApiProxy.kt index 2e9c78c64..3f28ad9bc 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfGlowingApiProxy.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfGlowingApiProxy.kt @@ -3,8 +3,10 @@ package dev.slne.surf.api.paper.server.proxy import com.google.auto.service.AutoService import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader import dev.slne.surf.api.paper.glow.SurfGlowingApi +import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.common.NmsProvider +@NmsUseWithCaution @AutoService(SurfGlowingApi::class) class SurfGlowingApiProxy : SurfGlowingApi by NmsProvider.current.createGlowingApi() { diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsBridgeProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsBridgeProxy.kt new file mode 100644 index 000000000..20b49f916 --- /dev/null +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsBridgeProxy.kt @@ -0,0 +1,15 @@ +package dev.slne.surf.api.paper.server.proxy + +import com.google.auto.service.AutoService +import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge +import dev.slne.surf.api.paper.nms.common.NmsProvider + +@NmsUseWithCaution +@AutoService(SurfPaperNmsBridge::class) +class SurfPaperNmsBridgeProxy : SurfPaperNmsBridge by NmsProvider.current.createNmsBridge() { + init { + checkInstantiationByServiceLoader() + } +} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/TickThreadGuardProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/TickThreadGuardProxy.kt index 8e88cf241..60bfa9dfd 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/TickThreadGuardProxy.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/TickThreadGuardProxy.kt @@ -2,9 +2,11 @@ package dev.slne.surf.api.paper.server.proxy import com.google.auto.service.AutoService import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.common.NmsProvider import dev.slne.surf.api.paper.region.TickThreadGuard +@NmsUseWithCaution @AutoService(TickThreadGuard::class) class TickThreadGuardProxy : TickThreadGuard by NmsProvider.current.createTickThreadGuard() { From dac546d1053ca8f29231bb5adef4947a45c63b6f Mon Sep 17 00:00:00 2001 From: TheBjoRedCraft Date: Wed, 15 Apr 2026 17:43:02 +0200 Subject: [PATCH 21/34] feat: add LuckPerms integration for player permissions handling --- gradle/libs.versions.toml | 3 +- surf-api-core/surf-api-core/build.gradle.kts | 1 + .../api/core/luckperms/LuckPermsAccess.kt | 47 +++++++++++++++++++ .../slne/surf/api/paper/util/bukkit-util.kt | 12 +++++ .../surf/api/velocity/util/velocity-util.kt | 7 +++ 5 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/luckperms/LuckPermsAccess.kt diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4b7594449..0cbc1223a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -16,7 +16,7 @@ packetevents-plugin = "2.11.2" commandapi = "11.2.0" # LuckPerms -luckperms = "v5.5.0-bukkit" +luckperms = "5.4" # Scoreboard Library scoreboard-library = "2.7.3" @@ -151,6 +151,7 @@ flogger-slf4j-backend = { module = "com.google.flogger:flogger-slf4j-backend", v aide-reflection = { module = "tech.hiddenproject:aide-reflection", version.ref = "aide-reflection" } 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" } 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" } diff --git a/surf-api-core/surf-api-core/build.gradle.kts b/surf-api-core/surf-api-core/build.gradle.kts index 41b104fb7..961052634 100644 --- a/surf-api-core/surf-api-core/build.gradle.kts +++ b/surf-api-core/surf-api-core/build.gradle.kts @@ -6,6 +6,7 @@ plugins { dependencies { api(projects.surfApiShared.surfApiSharedPublic) api(libs.adventure.nbt) + compileOnlyApi(libs.luckperms) compileOnlyApi(libs.packetevents.api) compileOnlyApi(libs.dazzleconf) compileOnlyApi(libs.spongepowered.math) diff --git a/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/luckperms/LuckPermsAccess.kt b/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/luckperms/LuckPermsAccess.kt new file mode 100644 index 000000000..6df1636b0 --- /dev/null +++ b/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/luckperms/LuckPermsAccess.kt @@ -0,0 +1,47 @@ +package dev.slne.surf.api.core.luckperms + +import dev.slne.surf.api.core.messages.adventure.uuidOrNull +import kotlinx.coroutines.future.await +import net.kyori.adventure.audience.Audience +import net.luckperms.api.LuckPermsProvider +import net.luckperms.api.model.user.User +import net.luckperms.api.node.NodeType +import java.util.* + +object LuckPermsAccess { + val luckperms by lazy { + LuckPermsProvider.get() + } + + fun getUser(uuid: UUID) = luckperms.userManager.getUser(uuid) + suspend fun loadUser(uuid: UUID): User = luckperms.userManager.loadUser(uuid).await() +} + +val User.prefix: String + get() = this.cachedData.metaData.prefix ?: "" +val User.suffix: String + get() = this.cachedData.metaData.suffix ?: "" + +val User.weight + get() = LuckPermsAccess.luckperms.groupManager.getGroup(this.primaryGroup)?.weight ?: 0 + +inline fun User.getMeta(key: String): T? { + val value = this.resolveInheritedNodes(NodeType.META, this.queryOptions) + .find { it.metaKey == key } + ?.metaValue + + return value as? T +} + +inline fun User.getMeta(key: String, default: T): T { + val value = this.resolveInheritedNodes(NodeType.META, this.queryOptions) + .find { it.metaKey == key } + ?.metaValue + + return value as? T ?: default +} + + +fun Audience.getLuckPermsUser() = this.uuidOrNull()?.let { LuckPermsAccess.getUser(it) } +fun Audience.getLuckPermsUserOrNull() = this.uuidOrNull()?.let { LuckPermsAccess.getUser(it) } + ?: error("Audience does not have a valid UUID or LuckPerms user could not be found.") \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/util/bukkit-util.kt b/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/util/bukkit-util.kt index a1cc40154..a8c11de51 100644 --- a/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/util/bukkit-util.kt +++ b/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/util/bukkit-util.kt @@ -6,6 +6,7 @@ package dev.slne.surf.api.paper.util import com.github.shynixn.mccoroutine.folia.SuspendingPlugin import com.github.shynixn.mccoroutine.folia.entityDispatcher import com.github.shynixn.mccoroutine.folia.regionDispatcher +import dev.slne.surf.api.core.luckperms.LuckPermsAccess import dev.slne.surf.api.core.util.getCallerClass import dev.slne.surf.api.core.util.mutableObjectListOf import dev.slne.surf.api.paper.SurfApiPaper @@ -263,6 +264,17 @@ suspend fun World.getBlockAtAsync(pos: BlockPosition): Block { } } + +fun Player.getLuckPermsUser() = LuckPermsAccess.getUser(this.uniqueId) + ?: error("LuckPerms user not found for online player ${this.name}") + +fun Player.getLuckPermsUserOrNull() = LuckPermsAccess.getUser(this.uniqueId) + +suspend fun OfflinePlayer.getLuckPermsUser() = withContext(Dispatchers.IO) { + LuckPermsAccess.getUser(this@getLuckPermsUser.uniqueId) + ?: LuckPermsAccess.loadUser(this@getLuckPermsUser.uniqueId) +} + /** * Constructs a human-readable string representing the location, including coordinates and optionally * rotation data. diff --git a/surf-api-velocity/surf-api-velocity/src/main/kotlin/dev/slne/surf/api/velocity/util/velocity-util.kt b/surf-api-velocity/surf-api-velocity/src/main/kotlin/dev/slne/surf/api/velocity/util/velocity-util.kt index 160927c42..8dab464a2 100644 --- a/surf-api-velocity/surf-api-velocity/src/main/kotlin/dev/slne/surf/api/velocity/util/velocity-util.kt +++ b/surf-api-velocity/surf-api-velocity/src/main/kotlin/dev/slne/surf/api/velocity/util/velocity-util.kt @@ -1,2 +1,9 @@ package dev.slne.surf.api.velocity.util +import com.velocitypowered.api.proxy.Player +import dev.slne.surf.api.core.luckperms.LuckPermsAccess + +fun Player.getLuckPermsUser() = LuckPermsAccess.getUser(this.uniqueId) + ?: error("LuckPerms user not found for online player ${this.username}") + +fun Player.getLuckPermsUserOrNull() = LuckPermsAccess.getUser(this.uniqueId) \ No newline at end of file From 5cf0fd83e4dbe2d74754dc2b81f6648f425711a8 Mon Sep 17 00:00:00 2001 From: TheBjoRedCraft Date: Wed, 15 Apr 2026 17:49:35 +0200 Subject: [PATCH 22/34] feat: add getPrefixedName method for Player to include LuckPerms prefix --- .../main/kotlin/dev/slne/surf/api/paper/util/bukkit-util.kt | 5 +++++ .../kotlin/dev/slne/surf/api/velocity/util/velocity-util.kt | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/util/bukkit-util.kt b/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/util/bukkit-util.kt index a8c11de51..a1d738cc8 100644 --- a/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/util/bukkit-util.kt +++ b/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/util/bukkit-util.kt @@ -7,6 +7,8 @@ import com.github.shynixn.mccoroutine.folia.SuspendingPlugin import com.github.shynixn.mccoroutine.folia.entityDispatcher import com.github.shynixn.mccoroutine.folia.regionDispatcher import dev.slne.surf.api.core.luckperms.LuckPermsAccess +import dev.slne.surf.api.core.luckperms.prefix +import dev.slne.surf.api.core.minimessage.miniMessage import dev.slne.surf.api.core.util.getCallerClass import dev.slne.surf.api.core.util.mutableObjectListOf import dev.slne.surf.api.paper.SurfApiPaper @@ -275,6 +277,9 @@ suspend fun OfflinePlayer.getLuckPermsUser() = withContext(Dispatchers.IO) { ?: LuckPermsAccess.loadUser(this@getLuckPermsUser.uniqueId) } +fun Player.getPrefixedName() = + miniMessage.deserialize("${this.getLuckPermsUserOrNull()?.prefix ?: ""}${this.name}") + /** * Constructs a human-readable string representing the location, including coordinates and optionally * rotation data. diff --git a/surf-api-velocity/surf-api-velocity/src/main/kotlin/dev/slne/surf/api/velocity/util/velocity-util.kt b/surf-api-velocity/surf-api-velocity/src/main/kotlin/dev/slne/surf/api/velocity/util/velocity-util.kt index 8dab464a2..cd5a20966 100644 --- a/surf-api-velocity/surf-api-velocity/src/main/kotlin/dev/slne/surf/api/velocity/util/velocity-util.kt +++ b/surf-api-velocity/surf-api-velocity/src/main/kotlin/dev/slne/surf/api/velocity/util/velocity-util.kt @@ -2,8 +2,13 @@ package dev.slne.surf.api.velocity.util import com.velocitypowered.api.proxy.Player import dev.slne.surf.api.core.luckperms.LuckPermsAccess +import dev.slne.surf.api.core.luckperms.prefix +import dev.slne.surf.api.core.minimessage.miniMessage fun Player.getLuckPermsUser() = LuckPermsAccess.getUser(this.uniqueId) ?: error("LuckPerms user not found for online player ${this.username}") +fun Player.getPrefixedName() = + miniMessage.deserialize("${this.getLuckPermsUserOrNull()?.prefix ?: ""}${this.username}") + fun Player.getLuckPermsUserOrNull() = LuckPermsAccess.getUser(this.uniqueId) \ No newline at end of file From 8cd4aca6db6a3ffd638d8a3bdd933fe9dad806fa Mon Sep 17 00:00:00 2001 From: TheBjoRedCraft Date: Wed, 15 Apr 2026 18:05:09 +0200 Subject: [PATCH 23/34] chore: remove gitlab-ci.yml --- .gitlab-ci.yml | 36 ------------------------------------ 1 file changed, 36 deletions(-) delete mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index da77ba3b3..000000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,36 +0,0 @@ -stages: - - build - - publish - -variables: - GRADLE_USER_HOME: "$CI_PROJECT_DIR/.gradle" - MAVEN_USER_SETTINGS: "$CI_PROJECT_DIR/maven-settings.xml" - -cache: - paths: - - .gradle/caches - - .gradle/caches/** - -before_script: - - export GRADLE_USER_HOME=`pwd`/.gradle - - export GRADLE_OPTS="-Dorg.gradle.daemon=false -Dorg.gradle.parallel=false" - - mkdir -p ~/.m2 - - echo "$MAVEN_SETTINGS_XML" > ~/.m2/settings.xml - -build: - stage: build - image: gradle:latest - script: - - gradle clean shadowJar - - echo "Gefundene Artefakte:" - - find . -type f -path "**/build/libs/*.jar" ! -path "**/.gradle/**" -exec ls -lh {} \; - -publish: - stage: publish - image: gradle:latest - script: - - gradle publish - dependencies: - - build - rules: - - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH \ No newline at end of file From 857ccddfec445d7ec3b19cb55e2c3dab2677f9df Mon Sep 17 00:00:00 2001 From: twisti <76837088+twisti-dev@users.noreply.github.com> Date: Wed, 15 Apr 2026 21:23:59 +0200 Subject: [PATCH 24/34] =?UTF-8?q?=E2=9C=A8=20feat(nms):=20add=20multiversi?= =?UTF-8?q?on=20support=20with=20new=20channel=20injector=20and=20packet?= =?UTF-8?q?=20listener=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - introduce AbstractChannelInjector for handling packet injection across multiple NMS versions - implement V1_21_11ChannelInjector and V26_1ChannelInjector for specific NMS versions - create InternalNmsBridge and InternalPacketListenerApiBridge for packet handling - update NmsProvider to create channel injectors and packet listener APIs --- .../build.gradle.kts | 2 +- .../nms/common/AbstractChannelInjector.kt | 210 +++++++++++++++ .../paper/nms/common}/InternalNmsBridge.kt | 5 +- .../common/InternalPacketListenerApiBridge.kt | 22 ++ .../surf/api/paper/nms/common/NmsProvider.kt | 4 + .../nms/v1_21_11/V1_21_11NmsProvider.kt | 4 + .../bridges/V1_21_11PacketListenerApiImpl.kt} | 36 ++- .../listener/V1_21_11ChannelInjector.kt | 102 ++++++++ .../server/nms/v26_1/V26_1NmsProvider.kt | 4 + .../bridges/V26_1PacketListenerApiImpl.kt | 229 ++++++++++++++++ .../packet/listener/V26_1ChannelInjector.kt | 102 ++++++++ .../paper/server/packet/PacketApiLoader.kt | 6 +- .../packet/listener/PlayerChannelInjector.kt | 245 ------------------ .../proxy/SurfPaperPacketListenerApiProxy.kt | 15 ++ 14 files changed, 716 insertions(+), 270 deletions(-) create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/AbstractChannelInjector.kt rename surf-api-paper/{surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/nms/bridge => surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common}/InternalNmsBridge.kt (93%) create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/InternalPacketListenerApiBridge.kt rename surf-api-paper/{surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/packet/listener/SurfPaperPacketListenerApiImpl.kt => surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11PacketListenerApiImpl.kt} (90%) create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/listener/V1_21_11ChannelInjector.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1PacketListenerApiImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1ChannelInjector.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/listener/PlayerChannelInjector.kt create mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperPacketListenerApiProxy.kt diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/build.gradle.kts b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/build.gradle.kts index 2f07109c5..93151e44f 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/build.gradle.kts +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/build.gradle.kts @@ -3,6 +3,6 @@ plugins { } dependencies { - api(projects.surfApiPaper.surfApiPaper) + compileOnlyApi(projects.surfApiPaper.surfApiPaper) compileOnly(libs.paper.api) } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/AbstractChannelInjector.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/AbstractChannelInjector.kt new file mode 100644 index 000000000..bcb90649e --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/AbstractChannelInjector.kt @@ -0,0 +1,210 @@ +package dev.slne.surf.api.paper.nms.common + +import dev.slne.surf.api.core.messages.Colors +import dev.slne.surf.api.core.messages.CommonComponents +import dev.slne.surf.api.core.messages.adventure.text +import dev.slne.surf.api.core.util.logger +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import io.netty.channel.Channel +import io.netty.channel.ChannelDuplexHandler +import io.netty.channel.ChannelHandlerContext +import io.netty.channel.ChannelPromise +import io.netty.util.AttributeKey +import net.kyori.adventure.key.Key +import org.bukkit.entity.Player +import org.bukkit.event.Listener +import org.bukkit.plugin.Plugin +import dev.slne.surf.api.paper.event.register as registerListener +import dev.slne.surf.api.paper.event.unregister as unregisterListener + +@OptIn(NmsUseWithCaution::class) +abstract class AbstractChannelInjector : Listener { + companion object { + private val log = logger() + + private val CHANNEL_KEY = Key.key("surf-api", "packet-listener") + private const val CHANNEL_NAME = "surf_api_packet_listener" + + val instance by lazy { NmsProvider.current.createChannelInjector() } + } + + private val packetHandlerKey = AttributeKey.newInstance("surf_api_packet_handler") + + /** + * The plugin instance used for listener registration. + */ + protected abstract val plugin: Plugin + + fun register() { + registerChannelInitializeListener(CHANNEL_KEY) { this.getOrInjectPacketHandler(it) } + registerListener(plugin) + } + + fun unregister() { + unregisterListener() + unregisterChannelInitializeListener(CHANNEL_KEY) + } + + @Suppress("SameParameterValue") + protected abstract fun registerChannelInitializeListener(key: Key, listener: (Channel) -> Unit) + + @Suppress("SameParameterValue") + protected abstract fun unregisterChannelInitializeListener(key: Key) + + protected abstract fun createPacketHandler(): H + protected abstract fun getNmsChannelHandlerName(): String + + protected fun getOrInjectPacketHandler(channel: Channel): H { + val handler = createPacketHandler() + val attr = channel.attr(packetHandlerKey) + + if (!attr.compareAndSet(null, handler)) { + return attr.get() + } + + val command = Runnable { + with(channel.pipeline()) { + if (get(CHANNEL_NAME) == null) { + addBefore(getNmsChannelHandlerName(), CHANNEL_NAME, handler) + } + } + } + + with(channel.eventLoop()) { + if (inEventLoop()) { + command.run() + } else { + execute(command) + } + } + + return handler + } + + protected fun createFailedToInjectPacketListenerDisconnectReason() = CommonComponents.renderDisconnectMessage( + "FAILED TO INJECT PACKET LISTENER", + { + text( + "Dein Profil ist nicht authentifiziert, daher können wir den Paket-Listener nicht einbinden. Dies ist wahrscheinlich ein Problem mit deiner Verbindung zu den Authentifizierungsservern von Mojang.", + Colors.ERROR + ) + }, + issue = true + ) + + @OptIn(NmsUseWithCaution::class) + abstract class AbstractPacketHandler : ChannelDuplexHandler() { + companion object { + val NO_CONNECTION_SENTINEL = Any() + } + + private val bridge = InternalNmsBridge.get() + private val packetListenerApi = InternalPacketListenerApiBridge.get() + private val packetBridgeHandler = NmsProvider.current.getPacketBridgeHandler() + + @OptIn(NmsUseWithCaution::class) + override fun write( + ctx: ChannelHandlerContext, + msg: Any, + promise: ChannelPromise, + ) { // server -> client + handlePacket( + originalMsg = msg, + passthrough = { super.write(ctx, it, promise) }, + nmsHandler = packetListenerApi::handleClientboundPacket, + bridgeHandler = ::handleClientboundPacketFromBridge + ) + } + + @OptIn(NmsUseWithCaution::class) + override fun channelRead(ctx: ChannelHandlerContext, msg: Any) { // client -> server + handlePacket( + originalMsg = msg, + passthrough = { super.channelRead(ctx, it) }, + nmsHandler = packetListenerApi::handleServerboundPacket, + bridgeHandler = ::handleServerboundPacketFromBridge + ) + } + + protected abstract fun isPacket(msg: Any): Boolean + protected abstract fun getPlayerFromConnection(): Any? + protected abstract fun getBukkitPlayer(player: Any?): Player? + + private inline fun handlePacket( + originalMsg: Any, + passthrough: (Any) -> Unit, + nmsHandler: (packet: Any, serverPlayer: Any?) -> Any?, + bridgeHandler: (player: Player?, packet: Any) -> Any? + ) { + var msg = originalMsg + if (!isPacket(msg)) { + passthrough(msg) + return + } + + val player = getPlayerFromConnection() + if (player === NO_CONNECTION_SENTINEL) { + passthrough(msg) + return + } + + try { + msg = nmsHandler(msg, player) ?: return + msg = bridgeHandler(getBukkitPlayer(player), msg) ?: return + passthrough(msg) + } catch (outOfMemoryError: OutOfMemoryError) { + throw outOfMemoryError + } catch (t: Throwable) { + log.atSevere() + .withCause(t).log("Failed to handle packet") + passthrough(msg) + } + } + + @OptIn(NmsUseWithCaution::class) + fun handleServerboundPacketFromBridge( + player: Player?, + packet: Any, + ): Any? { + val apiPacket = packetBridgeHandler.wrapServerboundPacket(packet) + + if (apiPacket != null) { // we have an api packet wrapper for this packet + val resultApi = this.bridge.handleServerboundPacket( + apiPacket, + player + ) + + if (resultApi != null) { // we may have a modified packet + return packetBridgeHandler.unwrapPacket(resultApi) + } + } else { + return packet // no api packet wrapper, so we just return the original packet + } + + return null // the packet was canceled + } + + fun handleClientboundPacketFromBridge( + player: Player?, + packet: Any, + ): Any? { + val apiPacket = packetBridgeHandler.wrapClientboundPacket(packet) + + if (apiPacket != null) { + val resultApi = this.bridge.handleClientboundPacket( + apiPacket, + player + ) + + if (resultApi != null) { + return packetBridgeHandler.unwrapPacket(resultApi) + } + } else { + return packet + } + + return null + } + } +} + diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/nms/bridge/InternalNmsBridge.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/InternalNmsBridge.kt similarity index 93% rename from surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/nms/bridge/InternalNmsBridge.kt rename to surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/InternalNmsBridge.kt index e86e4c52d..41932e053 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/nms/bridge/InternalNmsBridge.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/InternalNmsBridge.kt @@ -1,4 +1,4 @@ -package dev.slne.surf.api.paper.server.nms.bridge +package dev.slne.surf.api.paper.nms.common import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge @@ -21,4 +21,5 @@ interface InternalNmsBridge : SurfPaperNmsBridge { companion object { fun get() = SurfPaperNmsBridge.INSTANCE as InternalNmsBridge } -} \ No newline at end of file +} + diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/InternalPacketListenerApiBridge.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/InternalPacketListenerApiBridge.kt new file mode 100644 index 000000000..6896f3590 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/InternalPacketListenerApiBridge.kt @@ -0,0 +1,22 @@ +package dev.slne.surf.api.paper.nms.common + +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.packet.listener.SurfPaperPacketListenerApi + +@NmsUseWithCaution +interface InternalPacketListenerApiBridge : SurfPaperPacketListenerApi { + fun handleClientboundPacket( + packet: Any, + serverPlayer: Any? + ): Any? + + fun handleServerboundPacket( + packet: Any, + serverPlayer: Any? + ): Any? + + companion object { + fun get() = SurfPaperPacketListenerApi.INSTANCE as InternalPacketListenerApiBridge + } +} + diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt index c75c50863..360165d39 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt @@ -11,6 +11,7 @@ import dev.slne.surf.api.paper.nms.bridges.packets.entity.SurfPaperNmsSpawnPacke import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerChatPackets import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerPackets import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToastPackets +import dev.slne.surf.api.paper.packet.listener.SurfPaperPacketListenerApi import dev.slne.surf.api.paper.packet.listener.listener.PacketListener import dev.slne.surf.api.paper.region.TickThreadGuard import java.util.* @@ -75,6 +76,9 @@ interface NmsProvider { // ==================== Packet Listeners ==================== // + fun createChannelInjector(): AbstractChannelInjector<*> + fun createPacketListenerApi(): SurfPaperPacketListenerApi + /** * Creates version-specific packet listeners (e.g. lore handler, glowing handler). * diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt index 00372a673..3efac90ce 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt @@ -12,6 +12,7 @@ import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerChat import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerPackets import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToastPackets import dev.slne.surf.api.paper.nms.common.* +import dev.slne.surf.api.paper.packet.listener.SurfPaperPacketListenerApi import dev.slne.surf.api.paper.packet.listener.listener.PacketListener import dev.slne.surf.api.paper.region.TickThreadGuard import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.* @@ -23,6 +24,7 @@ import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.player.V1_21_ import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.player.V1_21_11SurfPaperNmsPlayerToastPacketsImpl import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.V1_21_11GlowingLifecycleHandler import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.V1_21_11SurfGlowingApiImpl +import dev.slne.surf.api.paper.server.nms.v1_21_11.packet.listener.V1_21_11ChannelInjector import dev.slne.surf.api.paper.server.nms.v1_21_11.packet.listener.V1_21_11GlowingPacketListener import dev.slne.surf.api.paper.server.nms.v1_21_11.packet.lore.V1_21_11PacketLoreListener import dev.slne.surf.api.paper.server.nms.v1_21_11.packet.lore.V1_21_11PacketLoreRegistry @@ -80,6 +82,8 @@ class V1_21_11NmsProvider : NmsProvider { V1_21_11GlowingLifecycleHandler() override fun createGlowingApi(): SurfGlowingApi = V1_21_11SurfGlowingApiImpl + override fun createChannelInjector(): AbstractChannelInjector<*> = V1_21_11ChannelInjector + override fun createPacketListenerApi(): SurfPaperPacketListenerApi = V1_21_11PacketListenerApiImpl() override fun createPacketListeners(): List = listOf( V1_21_11PacketLoreListener, diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/packet/listener/SurfPaperPacketListenerApiImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11PacketListenerApiImpl.kt similarity index 90% rename from surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/packet/listener/SurfPaperPacketListenerApiImpl.kt rename to surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11PacketListenerApiImpl.kt index cf095abcd..d0568e9c8 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/impl/packet/listener/SurfPaperPacketListenerApiImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11PacketListenerApiImpl.kt @@ -1,10 +1,9 @@ -package dev.slne.surf.api.paper.server.impl.packet.listener +package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges -import com.google.auto.service.AutoService import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader import dev.slne.surf.api.core.util.logger import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.packet.listener.SurfPaperPacketListenerApi +import dev.slne.surf.api.paper.nms.common.InternalPacketListenerApiBridge import dev.slne.surf.api.paper.packet.listener.listener.PacketListener import dev.slne.surf.api.paper.packet.listener.listener.PacketListenerResult import dev.slne.surf.api.paper.packet.listener.listener.annotation.ClientboundListener @@ -22,14 +21,13 @@ import java.util.concurrent.ConcurrentMap import java.util.concurrent.CopyOnWriteArraySet @NmsUseWithCaution -@AutoService(SurfPaperPacketListenerApi::class) -class SurfPaperPacketListenerApiImpl : SurfPaperPacketListenerApi { +class V1_21_11PacketListenerApiImpl : InternalPacketListenerApiBridge { + private typealias ListenerMethodsMap = ConcurrentHashMap, CopyOnWriteArraySet> + private val log = logger() - private val clientboundListenerMethods = - ConcurrentHashMap, CopyOnWriteArraySet>() - private val serverboundListenerMethods = - ConcurrentHashMap, CopyOnWriteArraySet>() + private val clientboundListenerMethods = ListenerMethodsMap() + private val serverboundListenerMethods = ListenerMethodsMap() private val lookup = MethodHandles.lookup() private val normalizedListenerType = MethodType.methodType( @@ -39,7 +37,7 @@ class SurfPaperPacketListenerApiImpl : SurfPaperPacketListenerApi { ) private val toBukkitPlayerHandle: MethodHandle = lookup.findStatic( - SurfPaperPacketListenerApiImpl::class.java, + V1_21_11PacketListenerApiImpl::class.java, "toBukkitPlayer", MethodType.methodType(Player::class.java, ServerPlayer::class.java) ) @@ -174,10 +172,10 @@ class SurfPaperPacketListenerApiImpl : SurfPaperPacketListenerApi { } } - fun handleClientboundPacket( - packet: Packet<*>, - serverPlayer: ServerPlayer? - ): Packet<*>? { + override fun handleClientboundPacket(packet: Any, serverPlayer: Any?): Any? { + packet as Packet<*> + serverPlayer as ServerPlayer? + val methods = clientboundListenerMethods[packet.javaClass] ?: return packet var result: Packet<*>? = packet @@ -195,10 +193,10 @@ class SurfPaperPacketListenerApiImpl : SurfPaperPacketListenerApi { return result } - fun handleServerboundPacket( - packet: Packet<*>, - serverPlayer: ServerPlayer? - ): Packet<*>? { + override fun handleServerboundPacket(packet: Any, serverPlayer: Any?): Any? { + packet as Packet<*> + serverPlayer as ServerPlayer? + val methods = serverboundListenerMethods[packet.javaClass] ?: return packet var result: Packet<*>? = packet @@ -228,4 +226,4 @@ class SurfPaperPacketListenerApiImpl : SurfPaperPacketListenerApi { val listener: PacketListener, val invoker: ListenerInvoker, ) -} +} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/listener/V1_21_11ChannelInjector.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/listener/V1_21_11ChannelInjector.kt new file mode 100644 index 000000000..8edb32478 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/listener/V1_21_11ChannelInjector.kt @@ -0,0 +1,102 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.packet.listener + +import dev.slne.surf.api.core.reflection.Field +import dev.slne.surf.api.core.reflection.SurfProxy +import dev.slne.surf.api.core.reflection.SurfReflection +import dev.slne.surf.api.core.reflection.createProxy +import dev.slne.surf.api.core.util.logger +import dev.slne.surf.api.paper.nms.common.AbstractChannelInjector +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.toNms +import io.netty.channel.Channel +import io.papermc.paper.connection.PaperPlayerLoginConnection +import io.papermc.paper.connection.ReadablePlayerCookieConnectionImpl +import io.papermc.paper.event.connection.PlayerConnectionValidateLoginEvent +import io.papermc.paper.network.ChannelInitializeListenerHolder +import net.kyori.adventure.key.Key +import net.minecraft.network.Connection +import net.minecraft.network.HandlerNames +import net.minecraft.network.protocol.Packet +import net.minecraft.server.level.ServerPlayer +import org.bukkit.entity.Player +import org.bukkit.event.EventHandler +import org.bukkit.event.EventPriority +import org.bukkit.event.player.PlayerJoinEvent +import org.bukkit.plugin.Plugin +import org.bukkit.plugin.java.JavaPlugin + +@Suppress("ClassName", "UnstableApiUsage") +object V1_21_11ChannelInjector : AbstractChannelInjector() { + private val log = logger() + + override val plugin: Plugin get() = JavaPlugin.getProvidingPlugin(V1_21_11ChannelInjector::class.java) + + override fun registerChannelInitializeListener( + key: Key, + listener: (Channel) -> Unit + ) { + ChannelInitializeListenerHolder.addListener(key, listener) + } + + override fun unregisterChannelInitializeListener(key: Key) { + ChannelInitializeListenerHolder.removeListener(key) + } + + override fun createPacketHandler() = PacketHandler() + override fun getNmsChannelHandlerName(): String = HandlerNames.PACKET_HANDLER + + @EventHandler + fun onPlayerLogin(event: PlayerConnectionValidateLoginEvent) { + val paperConnection = event.connection + if (paperConnection is PaperPlayerLoginConnection) { + val profile = paperConnection.authenticatedProfile + + if (profile == null) { + event.kickMessage(createFailedToInjectPacketListenerDisconnectReason()) + + log.atWarning() + .log("Failed to inject packet listener for player (${paperConnection.unsafeProfile}) with unauthenticated profile: ${paperConnection.address} - ${paperConnection.clientAddress}") + return + } + + val connection = + ReadablePlayerCookieConnectionImplProxy.instance.getConnection(paperConnection) + val channel = connection.channel + getOrInjectPacketHandler(channel).connection = connection + } + } + + @EventHandler(priority = EventPriority.LOWEST) + fun onPlayerJoin(event: PlayerJoinEvent) { + val player = event.player.toNms() + val connection = player.connection.connection + val channel = connection.channel + + getOrInjectPacketHandler(channel).connection = connection + } + + class PacketHandler : AbstractPacketHandler() { + @Volatile + var connection: Connection? = null + + override fun isPacket(msg: Any): Boolean = msg is Packet<*> + override fun getPlayerFromConnection(): Any? { + val connection = this.connection ?: return NO_CONNECTION_SENTINEL + return connection.player as ServerPlayer? + } + + override fun getBukkitPlayer(player: Any?): Player? { + return (player as? ServerPlayer)?.bukkitEntity + } + } + + @SurfProxy(ReadablePlayerCookieConnectionImpl::class) + interface ReadablePlayerCookieConnectionImplProxy { + + @Field("connection", Field.Type.GETTER) + fun getConnection(instance: ReadablePlayerCookieConnectionImpl): Connection + + companion object { + val instance = SurfReflection.createProxy() + } + } +} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt index 038ba54b9..3297ab643 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt @@ -12,6 +12,7 @@ import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerChat import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerPackets import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToastPackets import dev.slne.surf.api.paper.nms.common.* +import dev.slne.surf.api.paper.packet.listener.SurfPaperPacketListenerApi import dev.slne.surf.api.paper.packet.listener.listener.PacketListener import dev.slne.surf.api.paper.region.TickThreadGuard import dev.slne.surf.api.paper.server.nms.v26_1.bridges.* @@ -23,6 +24,7 @@ import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.player.V26_1Surf import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.player.V26_1SurfPaperNmsPlayerToastPacketsImpl import dev.slne.surf.api.paper.server.nms.v26_1.glow.V26_1GlowingLifecycleHandler import dev.slne.surf.api.paper.server.nms.v26_1.glow.V26_1SurfGlowingApiImpl +import dev.slne.surf.api.paper.server.nms.v26_1.packet.listener.V26_1ChannelInjector import dev.slne.surf.api.paper.server.nms.v26_1.packet.listener.V26_1GlowingPacketListener import dev.slne.surf.api.paper.server.nms.v26_1.packet.lore.V26_1PacketLoreListener import dev.slne.surf.api.paper.server.nms.v26_1.packet.lore.V26_1PacketLoreRegistry @@ -81,6 +83,8 @@ class V26_1NmsProvider : NmsProvider { V26_1GlowingLifecycleHandler() override fun createGlowingApi(): SurfGlowingApi = V26_1SurfGlowingApiImpl + override fun createChannelInjector(): AbstractChannelInjector<*> = V26_1ChannelInjector + override fun createPacketListenerApi(): SurfPaperPacketListenerApi = V26_1PacketListenerApiImpl() override fun createPacketListeners(): List = listOf( V26_1PacketLoreListener, diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1PacketListenerApiImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1PacketListenerApiImpl.kt new file mode 100644 index 000000000..1c407881d --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1PacketListenerApiImpl.kt @@ -0,0 +1,229 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.bridges + +import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.core.util.logger +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.common.InternalPacketListenerApiBridge +import dev.slne.surf.api.paper.packet.listener.listener.PacketListener +import dev.slne.surf.api.paper.packet.listener.listener.PacketListenerResult +import dev.slne.surf.api.paper.packet.listener.listener.annotation.ClientboundListener +import dev.slne.surf.api.paper.packet.listener.listener.annotation.ServerboundListener +import net.minecraft.network.protocol.Packet +import net.minecraft.server.level.ServerPlayer +import org.bukkit.entity.Player +import java.lang.invoke.MethodHandle +import java.lang.invoke.MethodHandles +import java.lang.invoke.MethodType +import java.lang.reflect.Method +import java.lang.reflect.Modifier +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.ConcurrentMap +import java.util.concurrent.CopyOnWriteArraySet + +@NmsUseWithCaution +class V26_1PacketListenerApiImpl : InternalPacketListenerApiBridge { + private typealias ListenerMethodsMap = ConcurrentHashMap, CopyOnWriteArraySet> + + private val log = logger() + + private val clientboundListenerMethods = ListenerMethodsMap() + private val serverboundListenerMethods = ListenerMethodsMap() + private val lookup = MethodHandles.lookup() + + private val normalizedListenerType = MethodType.methodType( + Any::class.java, + Packet::class.java, + ServerPlayer::class.java + ) + + private val toBukkitPlayerHandle: MethodHandle = lookup.findStatic( + V26_1PacketListenerApiImpl::class.java, + "toBukkitPlayer", + MethodType.methodType(Player::class.java, ServerPlayer::class.java) + ) + + companion object { + @Suppress("unused") + @JvmStatic + fun toBukkitPlayer(serverPlayer: ServerPlayer?): Player? = serverPlayer?.bukkitEntity + } + + init { + checkInstantiationByServiceLoader() + } + + override fun registerListeners(listener: PacketListener) { + for (method in listener.javaClass.declaredMethods) { + try { + if (method.isAnnotationPresent(ClientboundListener::class.java)) { + registerListenerMethod(listener, method, clientboundListenerMethods) + } else if (method.isAnnotationPresent(ServerboundListener::class.java)) { + registerListenerMethod(listener, method, serverboundListenerMethods) + } + } catch (e: IllegalAccessException) { + log.atSevere() + .withCause(e) + .log("Failed to register listener method '${method.declaringClass.name}#${method.name}' due to illegal access") + } + } + } + + private fun registerListenerMethod( + listener: PacketListener, + method: Method, + listenerMethods: ConcurrentMap, CopyOnWriteArraySet> + ) { + require(!Modifier.isStatic(method.modifiers)) { "Listener method must not be static: ${method.declaringClass.name}#${method.name}" } + require(method.parameterCount in 1..2) { "Listener method must have 1 or 2 parameters (Packet and optional ServerPlayer/Player): ${method.declaringClass.name}#${method.name}" } + + val packetParameterType = method.parameterTypes[0] + require(Packet::class.java.isAssignableFrom(packetParameterType)) { "Packet parameter must be a subclass of Packet: ${method.declaringClass.name}#${method.name}" } + + val playerParameterType = method.parameterTypes.getOrNull(1) + val hasServerPlayerParameter = + playerParameterType != null && ServerPlayer::class.java.isAssignableFrom( + playerParameterType + ) + + if (playerParameterType != null) { + val isBukkitPlayer = Player::class.java.isAssignableFrom(playerParameterType) + require(isBukkitPlayer || hasServerPlayerParameter) { "Second parameter must be either ServerPlayer or a Bukkit Player: ${method.declaringClass.name}#${method.name}" } + } + + val privateLookupIn = try { + MethodHandles.privateLookupIn(method.declaringClass, lookup) + } catch (_: IllegalAccessException) { + method.trySetAccessible() + lookup + } + + val methodHandle = createNormalizedInvokerHandle(listener, method, privateLookupIn) + val listeners = + listenerMethods.computeIfAbsent(packetParameterType) { CopyOnWriteArraySet() } + val invoker = createInvoker(methodHandle, method.returnType) + + listeners.add(ListenerMethod(listener, invoker)) + } + + private fun createNormalizedInvokerHandle( + listener: PacketListener, + method: Method, + lookup: MethodHandles.Lookup + ): MethodHandle { + val bound = lookup.unreflect(method).bindTo(listener) + val parameterTypes = method.parameterTypes + + val adapted = when (parameterTypes.size) { + 1 -> { + MethodHandles.dropArguments(bound, 1, ServerPlayer::class.java) + } + + 2 -> { + val second = parameterTypes[1] + + when { + ServerPlayer::class.java.isAssignableFrom(second) -> bound + Player::class.java.isAssignableFrom(second) -> + MethodHandles.filterArguments(bound, 1, toBukkitPlayerHandle) + + else -> error("Unsupported second parameter: $second") + } + } + + else -> error("Unsupported parameter count: ${parameterTypes.size}") + } + + return adapted.asType(normalizedListenerType) + } + + @Suppress("UNCHECKED_CAST") + private fun createInvoker( + mh: MethodHandle, + returnType: Class<*> + ): ListenerInvoker { + val resultConverter = createResultConverter(returnType) as ListenerResultConverter + return { packet, player -> + @Suppress("USELESS_CAST") + val result: Any? = mh.invokeExact(packet as Packet<*>, player as ServerPlayer?) + resultConverter.convert(result, packet) + } + } + + private fun createResultConverter(returnType: Class<*>): ListenerResultConverter<*> = when { + returnType == Void.TYPE -> ListenerResultConverter { _, p -> p } + returnType == PacketListenerResult::class.java -> ListenerResultConverter { result, packet -> + if (result == PacketListenerResult.CANCEL) null else packet + } + + Packet::class.java.isAssignableFrom(returnType) -> ListenerResultConverter?> { result, original -> + result + } + + else -> error("Unsupported return type for packet listener method: $returnType! Only void, PacketListenerResult, or a subclass of Packet is supported.") + } + + + override fun unregisterListeners(listener: PacketListener) { + for (methods in clientboundListenerMethods.values) { + methods.removeIf { it.listener == listener } + } + for (methods in serverboundListenerMethods.values) { + methods.removeIf { it.listener == listener } + } + } + + override fun handleClientboundPacket(packet: Any, serverPlayer: Any?): Any? { + packet as Packet<*> + serverPlayer as ServerPlayer? + + val methods = clientboundListenerMethods[packet.javaClass] ?: return packet + var result: Packet<*>? = packet + + try { + for (listenerMethod in methods) { + result = listenerMethod.invoker.invoke(result ?: break, serverPlayer) + if (result == null) break + } + } catch (t: Throwable) { + log.atSevere() + .withCause(t) + .log("Failed to handle clientbound packet") + } + + return result + } + + override fun handleServerboundPacket(packet: Any, serverPlayer: Any?): Any? { + packet as Packet<*> + serverPlayer as ServerPlayer? + + val methods = serverboundListenerMethods[packet.javaClass] ?: return packet + var result: Packet<*>? = packet + + try { + for (listenerMethod in methods) { + result = listenerMethod.invoker.invoke(result ?: break, serverPlayer) + if (result == null) break + } + } catch (t: Throwable) { + log.atSevere() + .withCause(t) + .log("Failed to handle serverbound packet") + } + + return result + } + + fun interface ListenerResultConverter { + fun convert(result: T?, packet: Packet<*>?): Packet<*>? + } + + fun interface ListenerInvoker { + fun invoke(packet: Packet<*>, serverPlayer: ServerPlayer?): Packet<*>? + } + + private data class ListenerMethod( + val listener: PacketListener, + val invoker: ListenerInvoker, + ) +} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1ChannelInjector.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1ChannelInjector.kt new file mode 100644 index 000000000..072fbe219 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1ChannelInjector.kt @@ -0,0 +1,102 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.packet.listener + +import dev.slne.surf.api.core.reflection.Field +import dev.slne.surf.api.core.reflection.SurfProxy +import dev.slne.surf.api.core.reflection.SurfReflection +import dev.slne.surf.api.core.reflection.createProxy +import dev.slne.surf.api.core.util.logger +import dev.slne.surf.api.paper.nms.common.AbstractChannelInjector +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.toNms +import io.netty.channel.Channel +import io.papermc.paper.connection.PaperPlayerLoginConnection +import io.papermc.paper.connection.ReadablePlayerCookieConnectionImpl +import io.papermc.paper.event.connection.PlayerConnectionValidateLoginEvent +import io.papermc.paper.network.ChannelInitializeListenerHolder +import net.kyori.adventure.key.Key +import net.minecraft.network.Connection +import net.minecraft.network.HandlerNames +import net.minecraft.network.protocol.Packet +import net.minecraft.server.level.ServerPlayer +import org.bukkit.entity.Player +import org.bukkit.event.EventHandler +import org.bukkit.event.EventPriority +import org.bukkit.event.player.PlayerJoinEvent +import org.bukkit.plugin.Plugin +import org.bukkit.plugin.java.JavaPlugin + +@Suppress("ClassName", "UnstableApiUsage") +object V26_1ChannelInjector : AbstractChannelInjector() { + private val log = logger() + + override val plugin: Plugin get() = JavaPlugin.getProvidingPlugin(V26_1ChannelInjector::class.java) + + override fun registerChannelInitializeListener( + key: Key, + listener: (Channel) -> Unit + ) { + ChannelInitializeListenerHolder.addListener(key, listener) + } + + override fun unregisterChannelInitializeListener(key: Key) { + ChannelInitializeListenerHolder.removeListener(key) + } + + override fun createPacketHandler() = PacketHandler() + override fun getNmsChannelHandlerName(): String = HandlerNames.PACKET_HANDLER + + @EventHandler + fun onPlayerLogin(event: PlayerConnectionValidateLoginEvent) { + val paperConnection = event.connection + if (paperConnection is PaperPlayerLoginConnection) { + val profile = paperConnection.authenticatedProfile + + if (profile == null) { + event.kickMessage(createFailedToInjectPacketListenerDisconnectReason()) + + log.atWarning() + .log("Failed to inject packet listener for player (${paperConnection.unsafeProfile}) with unauthenticated profile: ${paperConnection.address} - ${paperConnection.clientAddress}") + return + } + + val connection = + ReadablePlayerCookieConnectionImplProxy.instance.getConnection(paperConnection) + val channel = connection.channel + getOrInjectPacketHandler(channel).connection = connection + } + } + + @EventHandler(priority = EventPriority.LOWEST) + fun onPlayerJoin(event: PlayerJoinEvent) { + val player = event.player.toNms() + val connection = player.connection.connection + val channel = connection.channel + + getOrInjectPacketHandler(channel).connection = connection + } + + class PacketHandler : AbstractPacketHandler() { + @Volatile + var connection: Connection? = null + + override fun isPacket(msg: Any): Boolean = msg is Packet<*> + override fun getPlayerFromConnection(): Any? { + val connection = this.connection ?: return NO_CONNECTION_SENTINEL + return connection.player as ServerPlayer? + } + + override fun getBukkitPlayer(player: Any?): Player? { + return (player as? ServerPlayer)?.bukkitEntity + } + } + + @SurfProxy(ReadablePlayerCookieConnectionImpl::class) + interface ReadablePlayerCookieConnectionImplProxy { + + @Field("connection", Field.Type.GETTER) + fun getConnection(instance: ReadablePlayerCookieConnectionImpl): Connection + + companion object { + val instance = SurfReflection.createProxy() + } + } +} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt index b0f9cbe21..d2acb1200 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt @@ -5,10 +5,10 @@ import dev.slne.surf.api.core.extensions.packetEvents import dev.slne.surf.api.paper.event.register import dev.slne.surf.api.paper.event.unregister import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.common.AbstractChannelInjector import dev.slne.surf.api.paper.nms.common.NmsProvider import dev.slne.surf.api.paper.packet.listener.SurfPaperPacketListenerApi import dev.slne.surf.api.paper.packet.listener.listener.PacketListener -import dev.slne.surf.api.paper.server.packet.listener.PlayerChannelInjector import dev.slne.surf.api.paper.server.packet.lore.PluginDisablePacketLoreListener import dev.slne.surf.api.paper.server.plugin import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder @@ -33,7 +33,7 @@ object PacketApiLoader { SurfPaperPacketListenerApi.registerListeners(listener) } - PlayerChannelInjector.register() + AbstractChannelInjector.instance.register() PluginDisablePacketLoreListener.register() provider.initialize() @@ -51,7 +51,7 @@ object PacketApiLoader { versionPacketListeners = emptyList() PluginDisablePacketLoreListener.unregister() - PlayerChannelInjector.unregister() + AbstractChannelInjector.instance.unregister() } private fun setupPacketEvents() { diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/listener/PlayerChannelInjector.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/listener/PlayerChannelInjector.kt deleted file mode 100644 index 842b2e80b..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/listener/PlayerChannelInjector.kt +++ /dev/null @@ -1,245 +0,0 @@ -package dev.slne.surf.api.paper.server.packet.listener - -import dev.slne.surf.api.core.messages.Colors -import dev.slne.surf.api.core.messages.CommonComponents -import dev.slne.surf.api.core.messages.adventure.text -import dev.slne.surf.api.core.reflection.Field -import dev.slne.surf.api.core.reflection.SurfProxy -import dev.slne.surf.api.core.reflection.SurfReflection -import dev.slne.surf.api.core.reflection.createProxy -import dev.slne.surf.api.core.util.logger -import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.common.NmsProvider -import dev.slne.surf.api.paper.packet.listener.SurfPaperPacketListenerApi -import dev.slne.surf.api.paper.server.impl.packet.listener.SurfPaperPacketListenerApiImpl -import dev.slne.surf.api.paper.server.nms.bridge.InternalNmsBridge -import dev.slne.surf.api.paper.server.nms.toNms -import dev.slne.surf.api.paper.server.plugin -import io.netty.channel.Channel -import io.netty.channel.ChannelDuplexHandler -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.ChannelPromise -import io.netty.util.AttributeKey -import io.papermc.paper.connection.PaperPlayerLoginConnection -import io.papermc.paper.connection.ReadablePlayerCookieConnectionImpl -import io.papermc.paper.event.connection.PlayerConnectionValidateLoginEvent -import io.papermc.paper.network.ChannelInitializeListenerHolder -import net.kyori.adventure.key.Key -import net.minecraft.network.Connection -import net.minecraft.network.HandlerNames -import net.minecraft.network.protocol.Packet -import net.minecraft.server.level.ServerPlayer -import org.bukkit.event.EventHandler -import org.bukkit.event.EventPriority -import org.bukkit.event.Listener -import org.bukkit.event.player.PlayerJoinEvent -import dev.slne.surf.api.paper.event.register as registerListener -import dev.slne.surf.api.paper.event.unregister as unregisterListener - -@Suppress("UnstableApiUsage") -object PlayerChannelInjector : Listener { - private val log = logger() - - private val CHANNEL_KEY = Key.key("surf-api", "packet-listener") - private const val CHANNEL_NAME = "surf_api_packet_listener" - - private val packetHandlerKey = - AttributeKey.newInstance("surf_api_packet_handler") - - fun register() { - ChannelInitializeListenerHolder.addListener(CHANNEL_KEY) { this.getOrInjectPacketHandler(it) } - registerListener(plugin) - } - - fun unregister() { - unregisterListener() - ChannelInitializeListenerHolder.removeListener(CHANNEL_KEY) - } - - private fun getOrInjectPacketHandler(channel: Channel): PacketHandler { - val handler = PacketHandler() - val attr = channel.attr(packetHandlerKey) - - if (!attr.compareAndSet(null, handler)) { - return attr.get() - } - - val command = Runnable { - if (channel.pipeline().get(CHANNEL_NAME) == null) { - channel.pipeline().addBefore(HandlerNames.PACKET_HANDLER, CHANNEL_NAME, handler) - } - } - - if (channel.eventLoop().inEventLoop()) { - command.run() - } else { - channel.eventLoop().execute(command) - } - - return handler - } - - @EventHandler - fun onPlayerLogin(event: PlayerConnectionValidateLoginEvent) { - val paperConnection = event.connection - if (paperConnection is PaperPlayerLoginConnection) { - val profile = paperConnection.authenticatedProfile - - if (profile == null) { - event.kickMessage( - CommonComponents.renderDisconnectMessage( - "FAILED TO INJECT PACKET LISTENER", - { - text( - "Dein Profil ist nicht authentifiziert, daher können wir den Paket-Listener nicht einbinden. Dies ist wahrscheinlich ein Problem mit deiner Verbindung zu den Authentifizierungsservern von Mojang.", - Colors.ERROR - ) - }, - issue = true - ) - ) - - log.atWarning() - .log("Failed to inject packet listener for player (${paperConnection.unsafeProfile}) with unauthenticated profile: ${paperConnection.address} - ${paperConnection.clientAddress}") - return - } - - val connection = - ReadablePlayerCookieConnectionImplProxy.instance.getConnection(paperConnection) - val channel = connection.channel - getOrInjectPacketHandler(channel).connection = connection - } - } - - @EventHandler(priority = EventPriority.LOWEST) - fun onPlayerJoin(event: PlayerJoinEvent) { - val player = event.player.toNms() - val connection = player.connection.connection - val channel = connection.channel - - getOrInjectPacketHandler(channel).connection = connection - } - - @OptIn(NmsUseWithCaution::class) - private class PacketHandler : ChannelDuplexHandler() { - private val bridge = InternalNmsBridge.get() - private val packetListenerApi = - SurfPaperPacketListenerApi.INSTANCE as SurfPaperPacketListenerApiImpl - private val packetBridgeHandler = NmsProvider.current.getPacketBridgeHandler() - - @Volatile - var connection: Connection? = null - - @OptIn(NmsUseWithCaution::class) - override fun write( - ctx: ChannelHandlerContext, - msg: Any, - promise: ChannelPromise, - ) { // server -> client - handlePacket( - originalMsg = msg, - passthrough = { super.write(ctx, it, promise) }, - nmsHandler = packetListenerApi::handleClientboundPacket, - bridgeHandler = ::handleClientboundPacketFromBridge - ) - } - - @OptIn(NmsUseWithCaution::class) - override fun channelRead(ctx: ChannelHandlerContext, msg: Any) { // client -> server - handlePacket( - originalMsg = msg, - passthrough = { super.channelRead(ctx, it) }, - nmsHandler = packetListenerApi::handleServerboundPacket, - bridgeHandler = ::handleServerboundPacketFromBridge - ) - } - - private inline fun handlePacket( - originalMsg: Any, - passthrough: (Any) -> Unit, - nmsHandler: (Packet<*>, ServerPlayer?) -> Packet<*>?, - bridgeHandler: (ServerPlayer?, Packet<*>) -> Packet<*>? - ) { - var msg = originalMsg - if (msg !is Packet<*>) { - passthrough(msg) - return - } - - val connection = connection - if (connection == null) { - passthrough(msg) - return - } - - val player = connection.player as ServerPlayer? - - try { - msg = nmsHandler(msg, player) ?: return - msg = bridgeHandler(player, msg) ?: return - passthrough(msg) - } catch (outOfMemoryError: OutOfMemoryError) { - throw outOfMemoryError - } catch (t: Throwable) { - log.atSevere().withCause(t).log("Failed to handle packet") - passthrough(msg) - } - } - - @OptIn(NmsUseWithCaution::class) - fun handleServerboundPacketFromBridge( - serverPlayer: ServerPlayer?, - packet: Packet<*>, - ): Packet<*>? { - val apiPacket = packetBridgeHandler.wrapServerboundPacket(packet) - - if (apiPacket != null) { // we have an api packet wrapper for this packet - val resultApi = this.bridge.handleServerboundPacket( - apiPacket, - serverPlayer?.bukkitEntity - ) - - if (resultApi != null) { // we may have a modified packet - return packetBridgeHandler.unwrapPacket(resultApi) as Packet<*> - } - } else { - return packet // no api packet wrapper, so we just return the original packet - } - - return null // the packet was canceled - } - - fun handleClientboundPacketFromBridge( - serverPlayer: ServerPlayer?, - packet: Packet<*>, - ): Packet<*>? { - val apiPacket = packetBridgeHandler.wrapClientboundPacket(packet) - - if (apiPacket != null) { - val resultApi = this.bridge.handleClientboundPacket( - apiPacket, - serverPlayer?.bukkitEntity - ) - - if (resultApi != null) { - return packetBridgeHandler.unwrapPacket(resultApi) as Packet<*> - } - } else { - return packet - } - - return null - } - } - - @SurfProxy(ReadablePlayerCookieConnectionImpl::class) - interface ReadablePlayerCookieConnectionImplProxy { - - @Field("connection", Field.Type.GETTER) - fun getConnection(instance: ReadablePlayerCookieConnectionImpl): Connection - - companion object { - val instance = SurfReflection.createProxy() - } - } -} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperPacketListenerApiProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperPacketListenerApiProxy.kt new file mode 100644 index 000000000..cdb0e3ac9 --- /dev/null +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperPacketListenerApiProxy.kt @@ -0,0 +1,15 @@ +package dev.slne.surf.api.paper.server.proxy + +import com.google.auto.service.AutoService +import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.common.NmsProvider +import dev.slne.surf.api.paper.packet.listener.SurfPaperPacketListenerApi + +@NmsUseWithCaution +@AutoService(SurfPaperPacketListenerApi::class) +class SurfPaperPacketListenerApiProxy : SurfPaperPacketListenerApi by NmsProvider.current.createPacketListenerApi() { + init { + checkInstantiationByServiceLoader() + } +} \ No newline at end of file From bf0dfd36670e063570568d4bed0acbc7cdf0c268 Mon Sep 17 00:00:00 2001 From: twisti <76837088+twisti-dev@users.noreply.github.com> Date: Wed, 15 Apr 2026 21:40:12 +0200 Subject: [PATCH 25/34] =?UTF-8?q?=E2=9C=A8=20feat(nms):=20implement=20LibL?= =?UTF-8?q?oaderBridge=20for=20multiversion=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add LibLoaderBridge interface for handling library loading across NMS versions - implement V1_21_11LibLoaderBridgeImpl and V26_1LibLoaderBridgeImpl for respective versions - refactor LibLoader to utilize the new bridge for compatibility management --- .../api/paper/nms/common/LibLoaderBridge.kt | 18 ++++++ .../surf/api/paper/nms/common/NmsProvider.kt | 1 + .../nms/v1_21_11/V1_21_11NmsProvider.kt | 2 + .../bridges/V1_21_11LibLoaderBridgeImpl.kt | 58 +++++++++++++++++++ .../server/nms/v26_1/V26_1NmsProvider.kt | 2 + .../v26_1/bridges/V26_1LibLoaderBridgeImpl.kt | 58 +++++++++++++++++++ .../surf-api-paper-server/build.gradle.kts | 5 +- .../surf/api/paper/server/libs/LibLoader.kt | 29 ++++------ .../server/libs/reflection/LibReflection.kt | 9 --- .../reflection/PaperPluginClassLoaderProxy.kt | 16 ----- .../api/paper/server/nms/nms-extensions.kt | 18 ------ .../paper/server/reflection/EntityProxy.kt | 23 -------- .../api/paper/server/reflection/Reflection.kt | 28 +-------- .../ServerConnectionListenerProxy.kt | 12 ---- .../reflection/ServerStatsCounterProxy.kt | 20 ------- .../VanillaArgumentProviderImplProxy.kt | 15 ----- .../VanillaArgumentProviderProxy.kt | 14 ----- 17 files changed, 155 insertions(+), 173 deletions(-) create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/LibLoaderBridge.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11LibLoaderBridgeImpl.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1LibLoaderBridgeImpl.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/libs/reflection/LibReflection.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/libs/reflection/PaperPluginClassLoaderProxy.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/nms/nms-extensions.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/EntityProxy.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/ServerConnectionListenerProxy.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/ServerStatsCounterProxy.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/VanillaArgumentProviderImplProxy.kt delete mode 100644 surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/VanillaArgumentProviderProxy.kt diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/LibLoaderBridge.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/LibLoaderBridge.kt new file mode 100644 index 000000000..0d407a1ad --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/LibLoaderBridge.kt @@ -0,0 +1,18 @@ +package dev.slne.surf.api.paper.nms.common + +import java.net.URLClassLoader + +interface LibLoaderBridge { + fun getActiveCompatibilities(): MutableSet + + fun convertWithCommodore( + b: ByteArray, + pluginName: String, + pluginVersion: String, + activeCompatibilities: MutableSet + ): ByteArray + + fun overwriteLibraryLoader(pluginClassLoader: URLClassLoader, newLoader: URLClassLoader) + + fun getLibraryLoader(pluginClassLoader: URLClassLoader): URLClassLoader +} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt index 360165d39..bac279a79 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt @@ -49,6 +49,7 @@ interface NmsProvider { fun createPlayerChatPackets(): SurfPaperNmsPlayerChatPackets fun createPlayerToastPackets(): SurfPaperNmsPlayerToastPackets fun createTickThreadGuard(): TickThreadGuard + fun getLibLoaderBridge(): LibLoaderBridge // ==================== Packet Bridge Handler ==================== // diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt index 3efac90ce..901ba123b 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt @@ -75,6 +75,8 @@ class V1_21_11NmsProvider : NmsProvider { V1_21_11SurfPaperNmsPlayerToastPacketsImpl() override fun createTickThreadGuard(): TickThreadGuard = V1_21_11TickThreadGuard() + override fun getLibLoaderBridge(): LibLoaderBridge = V1_21_11LibLoaderBridgeImpl + override fun getPacketBridgeHandler(): NmsPacketBridgeHandler = V1_21_11NmsPacketBridgeHandler override fun createPacketLoreRegistry(): PacketLoreRegistry = V1_21_11PacketLoreRegistry() diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11LibLoaderBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11LibLoaderBridgeImpl.kt new file mode 100644 index 000000000..376d3d9ae --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11LibLoaderBridgeImpl.kt @@ -0,0 +1,58 @@ +package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges + +import dev.slne.surf.api.core.reflection.Field +import dev.slne.surf.api.core.reflection.Field.Type +import dev.slne.surf.api.core.reflection.SurfProxy +import dev.slne.surf.api.core.reflection.SurfReflection +import dev.slne.surf.api.core.reflection.createProxy +import dev.slne.surf.api.core.util.setFinalField +import dev.slne.surf.api.paper.nms.common.LibLoaderBridge +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.commodore +import dev.slne.surf.api.paper.server.nms.v1_21_11.extensions.craftServer +import io.papermc.paper.plugin.entrypoint.classloader.PaperPluginClassLoader +import org.bukkit.craftbukkit.util.ApiVersion +import java.net.URLClassLoader + +@Suppress("ClassName") +object V1_21_11LibLoaderBridgeImpl : LibLoaderBridge { + + override fun getActiveCompatibilities(): MutableSet { + return craftServer.activeCompatibilities + } + + override fun convertWithCommodore( + b: ByteArray, + pluginName: String, + pluginVersion: String, + activeCompatibilities: MutableSet + ): ByteArray { + return commodore.convert( + b, + pluginName, + ApiVersion.getOrCreateVersion(pluginVersion), + activeCompatibilities + ) + } + + @Suppress("DEPRECATION") + override fun overwriteLibraryLoader(pluginClassLoader: URLClassLoader, newLoader: URLClassLoader) { + PaperPluginClassLoader::class.java.getDeclaredField("libraryLoader").apply { + setAccessible(true) + setFinalField(this, pluginClassLoader, newLoader) + } + } + + override fun getLibraryLoader(pluginClassLoader: URLClassLoader): URLClassLoader { + return PaperPluginClassLoaderProxy.instance.getLibraryLoader(pluginClassLoader as PaperPluginClassLoader) + } + + @SurfProxy(PaperPluginClassLoader::class) + interface PaperPluginClassLoaderProxy { + @Field("libraryLoader", Type.GETTER) + fun getLibraryLoader(instance: PaperPluginClassLoader): URLClassLoader + + companion object { + val instance = SurfReflection.createProxy() + } + } +} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt index 3297ab643..8754825f7 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt @@ -76,6 +76,8 @@ class V26_1NmsProvider : NmsProvider { V26_1SurfPaperNmsPlayerToastPacketsImpl() override fun createTickThreadGuard(): TickThreadGuard = V26_1TickThreadGuard() + override fun getLibLoaderBridge(): LibLoaderBridge = V26_1LibLoaderBridgeImpl + override fun getPacketBridgeHandler(): NmsPacketBridgeHandler = V26_1NmsPacketBridgeHandler override fun createPacketLoreRegistry(): PacketLoreRegistry = V26_1PacketLoreRegistry() diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1LibLoaderBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1LibLoaderBridgeImpl.kt new file mode 100644 index 000000000..3a99bd10d --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1LibLoaderBridgeImpl.kt @@ -0,0 +1,58 @@ +package dev.slne.surf.api.paper.server.nms.v26_1.bridges + +import dev.slne.surf.api.core.reflection.Field +import dev.slne.surf.api.core.reflection.Field.Type +import dev.slne.surf.api.core.reflection.SurfProxy +import dev.slne.surf.api.core.reflection.SurfReflection +import dev.slne.surf.api.core.reflection.createProxy +import dev.slne.surf.api.core.util.setFinalField +import dev.slne.surf.api.paper.nms.common.LibLoaderBridge +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.commodore +import dev.slne.surf.api.paper.server.nms.v26_1.extensions.craftServer +import io.papermc.paper.plugin.entrypoint.classloader.PaperPluginClassLoader +import org.bukkit.craftbukkit.util.ApiVersion +import java.net.URLClassLoader + +@Suppress("ClassName") +object V26_1LibLoaderBridgeImpl : LibLoaderBridge { + + override fun getActiveCompatibilities(): MutableSet { + return craftServer.activeCompatibilities + } + + override fun convertWithCommodore( + b: ByteArray, + pluginName: String, + pluginVersion: String, + activeCompatibilities: MutableSet + ): ByteArray { + return commodore.convert( + b, + pluginName, + ApiVersion.getOrCreateVersion(pluginVersion), + activeCompatibilities + ) + } + + @Suppress("DEPRECATION") + override fun overwriteLibraryLoader(pluginClassLoader: URLClassLoader, newLoader: URLClassLoader) { + PaperPluginClassLoader::class.java.getDeclaredField("libraryLoader").apply { + setAccessible(true) + setFinalField(this, pluginClassLoader, newLoader) + } + } + + override fun getLibraryLoader(pluginClassLoader: URLClassLoader): URLClassLoader { + return PaperPluginClassLoaderProxy.instance.getLibraryLoader(pluginClassLoader as PaperPluginClassLoader) + } + + @SurfProxy(PaperPluginClassLoader::class) + interface PaperPluginClassLoaderProxy { + @Field("libraryLoader", Type.GETTER) + fun getLibraryLoader(instance: PaperPluginClassLoader): URLClassLoader + + companion object { + val instance = SurfReflection.createProxy() + } + } +} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/build.gradle.kts b/surf-api-paper/surf-api-paper-server/build.gradle.kts index b9adbf5e1..46031b32d 100644 --- a/surf-api-paper/surf-api-paper-server/build.gradle.kts +++ b/surf-api-paper/surf-api-paper-server/build.gradle.kts @@ -6,7 +6,7 @@ plugins { `core-convention` alias(libs.plugins.plugin.yml.paper) - id("io.papermc.paperweight.userdev") apply true +// id("io.papermc.paperweight.userdev") apply true } kotlin { @@ -19,8 +19,9 @@ dependencies { api(projects.surfApiPaper.surfApiPaper) api(projects.surfApiCore.surfApiCoreServer) api(projects.surfApiPaper.surfApiPaperNms.surfApiPaperNmsCommon) + compileOnly(libs.paper.api) - paperweight.paperDevBundle(libs.paper.api.get().version) +// paperweight.paperDevBundle(libs.paper.api.get().version) runtimeOnly(projects.surfApiPaper.surfApiPaperNms.surfApiPaperNmsV12111) runtimeOnly(projects.surfApiPaper.surfApiPaperNms.surfApiPaperNmsV261) diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/libs/LibLoader.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/libs/LibLoader.kt index 57d4b275d..6b66b3a2e 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/libs/LibLoader.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/libs/LibLoader.kt @@ -3,15 +3,11 @@ package dev.slne.surf.api.paper.server.libs import dev.slne.surf.api.core.util.logger -import dev.slne.surf.api.core.util.setFinalField import dev.slne.surf.api.core.util.toEnumeration -import dev.slne.surf.api.paper.server.libs.reflection.LibReflection -import dev.slne.surf.api.paper.server.nms.commodore -import dev.slne.surf.api.paper.server.nms.craftServer +import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.common.NmsProvider import dev.slne.surf.api.paper.server.plugin -import io.papermc.paper.plugin.entrypoint.classloader.PaperPluginClassLoader import io.papermc.paper.plugin.provider.classloader.ConfiguredPluginClassLoader -import org.bukkit.craftbukkit.util.ApiVersion import java.io.IOException import java.io.InputStream import java.net.URL @@ -28,9 +24,11 @@ import kotlin.io.path.outputStream import kotlin.math.max import kotlin.math.min +@OptIn(NmsUseWithCaution::class) class LibLoader(pluginClassLoader: ClassLoader) { private val logger = logger() - private val pluginClassLoader = pluginClassLoader as PaperPluginClassLoader + private val bridge by lazy { NmsProvider.current.getLibLoaderBridge() } + private val pluginClassLoader = pluginClassLoader as URLClassLoader fun loadLibs() { } @@ -93,11 +91,11 @@ class LibLoader(pluginClassLoader: ClassLoader) { } private fun remapClass(jarName: String, clazz: ByteArray, apiVersion: String) = - commodore.convert( + bridge.convertWithCommodore( clazz, jarName, - ApiVersion.getOrCreateVersion(apiVersion), - craftServer.activeCompatibilities + apiVersion, + bridge.getActiveCompatibilities() ) private fun loadTempFileFromResource(fileName: String): Path? { @@ -136,18 +134,14 @@ class LibLoader(pluginClassLoader: ClassLoader) { @Suppress("DEPRECATION") private fun getOrCreateSurfLibClassLoader(): SurfLibJoinClassLoader { - val libraryLoader = - LibReflection.PAPER_PLUGIN_CLASS_LOADER_PROXY.getLibraryLoader(pluginClassLoader) + val libraryLoader = bridge.getLibraryLoader(pluginClassLoader) if (libraryLoader is SurfLibJoinClassLoader) { return libraryLoader } val surfLoader = SurfLibJoinClassLoader(libraryLoader) - PaperPluginClassLoader::class.java.getDeclaredField("libraryLoader").apply { - setAccessible(true) - setFinalField(this, pluginClassLoader, surfLoader) - } + bridge.overwriteLibraryLoader(pluginClassLoader, surfLoader) return surfLoader } @@ -157,7 +151,8 @@ class LibLoader(pluginClassLoader: ClassLoader) { private inner class SurfLibJoinClassLoader( parent: URLClassLoader, vararg delegateClassLoaders: URLClassLoader, - ) : URLClassLoader(parent.urLs, parent), ConfiguredPluginClassLoader by pluginClassLoader { + ) : URLClassLoader(parent.urLs, parent), + ConfiguredPluginClassLoader by pluginClassLoader as ConfiguredPluginClassLoader { private val delegateClassLoaders = delegateClassLoaders.toMutableList() override fun findClass(name: String): Class<*>? { diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/libs/reflection/LibReflection.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/libs/reflection/LibReflection.kt deleted file mode 100644 index f9bc6298d..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/libs/reflection/LibReflection.kt +++ /dev/null @@ -1,9 +0,0 @@ -package dev.slne.surf.api.paper.server.libs.reflection - -import dev.slne.surf.api.core.reflection.SurfReflection -import dev.slne.surf.api.core.reflection.createProxy - -object LibReflection { - @JvmField - val PAPER_PLUGIN_CLASS_LOADER_PROXY = SurfReflection.createProxy() -} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/libs/reflection/PaperPluginClassLoaderProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/libs/reflection/PaperPluginClassLoaderProxy.kt deleted file mode 100644 index 6a97c8c63..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/libs/reflection/PaperPluginClassLoaderProxy.kt +++ /dev/null @@ -1,16 +0,0 @@ -package dev.slne.surf.api.paper.server.libs.reflection - -import dev.slne.surf.api.core.reflection.Field -import dev.slne.surf.api.core.reflection.Field.Type -import dev.slne.surf.api.core.reflection.SurfProxy -import io.papermc.paper.plugin.entrypoint.classloader.PaperPluginClassLoader -import java.net.URLClassLoader - -@SurfProxy(PaperPluginClassLoader::class) -interface PaperPluginClassLoaderProxy { - @Field("libraryLoader", Type.SETTER, overrideFinal = true) - fun setLibraryLoader(instance: PaperPluginClassLoader, libraryLoader: URLClassLoader) - - @Field("libraryLoader", Type.GETTER) - fun getLibraryLoader(instance: PaperPluginClassLoader): URLClassLoader -} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/nms/nms-extensions.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/nms/nms-extensions.kt deleted file mode 100644 index f374249d7..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/nms/nms-extensions.kt +++ /dev/null @@ -1,18 +0,0 @@ -@file:Suppress("UnstableApiUsage") - -package dev.slne.surf.api.paper.server.nms - -import dev.slne.surf.api.paper.extensions.server -import net.minecraft.server.level.ServerPlayer -import org.bukkit.Server -import org.bukkit.craftbukkit.CraftServer -import org.bukkit.craftbukkit.entity.CraftPlayer -import org.bukkit.craftbukkit.util.Commodore -import org.bukkit.craftbukkit.util.CraftMagicNumbers -import org.bukkit.entity.Player - -fun Player.toNms(): ServerPlayer = (this as CraftPlayer).handle - -fun Server.toCraft() = this as CraftServer -val craftServer: CraftServer get() = server.toCraft() -val commodore: Commodore get() = CraftMagicNumbers.INSTANCE.commodore diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/EntityProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/EntityProxy.kt deleted file mode 100644 index f9a4a85c9..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/EntityProxy.kt +++ /dev/null @@ -1,23 +0,0 @@ -package dev.slne.surf.api.paper.server.reflection - -import net.minecraft.network.syncher.EntityDataAccessor -import net.minecraft.world.entity.Entity -import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldGetter -import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies -import xyz.jpenilla.reflectionremapper.proxy.annotation.Static - -@Proxies(Entity::class) -interface EntityProxy { - - @FieldGetter("FLAG_GLOWING") - @Static - fun getFlagGlowing(): Int - - @FieldGetter("FLAG_INVISIBLE") - @Static - fun getFlagInvisible(): Int - - @FieldGetter("DATA_SHARED_FLAGS_ID") - @Static - fun getDataFlagsSharedId(): EntityDataAccessor -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/Reflection.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/Reflection.kt index de4f9e054..7ff685aef 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/Reflection.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/Reflection.kt @@ -2,33 +2,7 @@ package dev.slne.surf.api.paper.server.reflection import dev.slne.surf.api.core.reflection.SurfReflection import dev.slne.surf.api.core.reflection.createProxy -import dev.slne.surf.api.paper.util.reflectionProxy -import xyz.jpenilla.reflectionremapper.ReflectionRemapper -import xyz.jpenilla.reflectionremapper.proxy.ReflectionProxyFactory object Reflection { - val SERVER_STATS_COUNTER_PROXY: ServerStatsCounterProxy - val ENTITY_PROXY: EntityProxy - val SERVER_CONNECTION_LISTENER_PROXY: ServerConnectionListenerProxy - val JAVA_PLUGIN_PROXY: JavaPluginProxy - val VANILLA_ARGUMENT_PROVIDER_IMPL_PROXY: VanillaArgumentProviderImplProxy - val VANILLA_ARGUMENT_PROVIDER_PROXY: VanillaArgumentProviderProxy - - init { - val remapper = ReflectionRemapper.forReobfMappingsInPaperJar() - val proxyFactory = - ReflectionProxyFactory.create(remapper, Reflection::class.java.classLoader) - - SERVER_STATS_COUNTER_PROXY = proxyFactory.reflectionProxy() - ENTITY_PROXY = proxyFactory.reflectionProxy() - SERVER_CONNECTION_LISTENER_PROXY = - proxyFactory.reflectionProxy() - JAVA_PLUGIN_PROXY = SurfReflection.createProxy() - VANILLA_ARGUMENT_PROVIDER_IMPL_PROXY = - SurfReflection.createProxy() - VANILLA_ARGUMENT_PROVIDER_PROXY = SurfReflection.createProxy() - - // gc the remapper - System.gc() - } + val JAVA_PLUGIN_PROXY: JavaPluginProxy = SurfReflection.createProxy() } diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/ServerConnectionListenerProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/ServerConnectionListenerProxy.kt deleted file mode 100644 index 9197b5b24..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/ServerConnectionListenerProxy.kt +++ /dev/null @@ -1,12 +0,0 @@ -package dev.slne.surf.api.paper.server.reflection - -import io.netty.channel.ChannelFuture -import net.minecraft.server.network.ServerConnectionListener -import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldGetter -import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies - -@Proxies(ServerConnectionListener::class) -interface ServerConnectionListenerProxy { - @FieldGetter("channels") - fun getChannels(instance: ServerConnectionListener): List -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/ServerStatsCounterProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/ServerStatsCounterProxy.kt deleted file mode 100644 index 818eaccee..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/ServerStatsCounterProxy.kt +++ /dev/null @@ -1,20 +0,0 @@ -package dev.slne.surf.api.paper.server.reflection - -import com.google.gson.Gson -import com.google.gson.JsonElement -import net.minecraft.stats.ServerStatsCounter -import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldGetter -import xyz.jpenilla.reflectionremapper.proxy.annotation.MethodName -import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies -import xyz.jpenilla.reflectionremapper.proxy.annotation.Static - -@Proxies(ServerStatsCounter::class) -interface ServerStatsCounterProxy { - - @MethodName("toJson") - fun toJson(statsCounter: ServerStatsCounter): JsonElement - - @FieldGetter("GSON") - @Static - fun getGson(): Gson -} diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/VanillaArgumentProviderImplProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/VanillaArgumentProviderImplProxy.kt deleted file mode 100644 index ee729ce8f..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/VanillaArgumentProviderImplProxy.kt +++ /dev/null @@ -1,15 +0,0 @@ -package dev.slne.surf.api.paper.server.reflection - -import com.mojang.brigadier.arguments.ArgumentType -import com.mojang.brigadier.exceptions.CommandSyntaxException -import dev.slne.surf.api.core.reflection.Name -import dev.slne.surf.api.core.reflection.SurfProxy -import io.papermc.paper.command.brigadier.argument.VanillaArgumentProviderImpl - -@SurfProxy(VanillaArgumentProviderImpl::class) -interface VanillaArgumentProviderImplProxy { - - @Name("wrap") - @Throws(CommandSyntaxException::class) - fun wrap(instance: Any, base: Any, converter: Any): ArgumentType<*> -} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/VanillaArgumentProviderProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/VanillaArgumentProviderProxy.kt deleted file mode 100644 index 0a9c9edda..000000000 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/reflection/VanillaArgumentProviderProxy.kt +++ /dev/null @@ -1,14 +0,0 @@ -package dev.slne.surf.api.paper.server.reflection - -import dev.slne.surf.api.core.reflection.Name -import dev.slne.surf.api.core.reflection.Static -import dev.slne.surf.api.core.reflection.SurfProxy - - -@SurfProxy(qualifiedName = "io.papermc.paper.command.brigadier.argument.VanillaArgumentProvider") -interface VanillaArgumentProviderProxy { - - @Static - @Name("provider") - fun provider(): Any -} \ No newline at end of file From a3f2c3fd9d032ec5edc7b19efbfe99651a6f5155 Mon Sep 17 00:00:00 2001 From: twisti <76837088+twisti-dev@users.noreply.github.com> Date: Thu, 16 Apr 2026 18:18:15 +0200 Subject: [PATCH 26/34] =?UTF-8?q?=E2=9C=A8=20feat(nms):=20add=20NMS=20prov?= =?UTF-8?q?ider=20support=20for=20multiple=20versions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - implement NmsProvider interface for version-specific operations - add NmsProviderConfig for managing provider metadata - create NmsProvidersCollector for collecting NMS providers at compile time - update existing channel injectors to use NmsProvider for plugin registration - enhance version resolution logic for better fallback handling --- .../dev/slne/surf/api/processor/ClassNames.kt | 2 + .../processor/nms/NmsProvidersCollector.kt | 79 ++++++++++++ .../nms/NmsProvidersCollectorProvider.kt | 11 ++ ...ols.ksp.processing.SymbolProcessorProvider | 3 +- .../build.gradle.kts | 1 + .../nms/common/AbstractChannelInjector.kt | 8 +- .../surf/api/paper/nms/common/NmsProvider.kt | 119 +++++++++++++----- .../surf/api/paper/nms/common/NmsVersion.kt | 40 ------ .../paper/nms/common/NmsVersionResolver.kt | 30 +++++ .../nms/v1_21_11/V1_21_11NmsProvider.kt | 9 +- .../bridges/V1_21_11PacketListenerApiImpl.kt | 5 - .../glow/V1_21_11SurfGlowingApiImpl.kt | 4 +- .../listener/V1_21_11ChannelInjector.kt | 4 - .../server/nms/v26_1/V26_1NmsProvider.kt | 8 +- .../bridges/V26_1PacketListenerApiImpl.kt | 5 - .../nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt | 4 +- .../packet/listener/V26_1ChannelInjector.kt | 4 - .../shared/internal/nms/NmsProviderConfig.kt | 12 ++ .../shared/internal/nms/NmsProviderMarker.kt | 5 + .../shared/internal/nms/NmsProviderMeta.kt | 9 ++ .../api/shared/internal/nms/NmsVersion.kt | 11 ++ 21 files changed, 265 insertions(+), 108 deletions(-) create mode 100644 surf-api-gradle-plugin/surf-api-processor/src/main/kotlin/dev/slne/surf/api/processor/nms/NmsProvidersCollector.kt create mode 100644 surf-api-gradle-plugin/surf-api-processor/src/main/kotlin/dev/slne/surf/api/processor/nms/NmsProvidersCollectorProvider.kt delete mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersion.kt create mode 100644 surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersionResolver.kt create mode 100644 surf-api-shared/surf-api-shared-internal/src/main/kotlin/dev/slne/surf/api/shared/internal/nms/NmsProviderConfig.kt create mode 100644 surf-api-shared/surf-api-shared-internal/src/main/kotlin/dev/slne/surf/api/shared/internal/nms/NmsProviderMarker.kt create mode 100644 surf-api-shared/surf-api-shared-internal/src/main/kotlin/dev/slne/surf/api/shared/internal/nms/NmsProviderMeta.kt create mode 100644 surf-api-shared/surf-api-shared-internal/src/main/kotlin/dev/slne/surf/api/shared/internal/nms/NmsVersion.kt diff --git a/surf-api-gradle-plugin/surf-api-processor/src/main/kotlin/dev/slne/surf/api/processor/ClassNames.kt b/surf-api-gradle-plugin/surf-api-processor/src/main/kotlin/dev/slne/surf/api/processor/ClassNames.kt index cff057e4d..a4c39eebf 100644 --- a/surf-api-gradle-plugin/surf-api-processor/src/main/kotlin/dev/slne/surf/api/processor/ClassNames.kt +++ b/surf-api-gradle-plugin/surf-api-processor/src/main/kotlin/dev/slne/surf/api/processor/ClassNames.kt @@ -5,6 +5,7 @@ import dev.slne.surf.api.shared.api.component.Priority import dev.slne.surf.api.shared.api.component.SurfComponentMeta import dev.slne.surf.api.shared.api.component.processor.ComponentPostProcessor import dev.slne.surf.api.shared.api.component.requirement.* +import dev.slne.surf.api.shared.internal.nms.NmsProviderMarker object ClassNames { val COMPONENT_META = nameOf() @@ -19,4 +20,5 @@ object ClassNames { val CONDITIONAL_ON_MISSING_COMPONENT = nameOf() val CONDITIONAL_ON_PROPERTY = nameOf() val COMPONENT_POST_PROCESSOR = nameOf() + val NMS_PROVIDER = nameOf() } \ No newline at end of file diff --git a/surf-api-gradle-plugin/surf-api-processor/src/main/kotlin/dev/slne/surf/api/processor/nms/NmsProvidersCollector.kt b/surf-api-gradle-plugin/surf-api-processor/src/main/kotlin/dev/slne/surf/api/processor/nms/NmsProvidersCollector.kt new file mode 100644 index 000000000..540d33661 --- /dev/null +++ b/surf-api-gradle-plugin/surf-api-processor/src/main/kotlin/dev/slne/surf/api/processor/nms/NmsProvidersCollector.kt @@ -0,0 +1,79 @@ +package dev.slne.surf.api.processor.nms + +import com.google.devtools.ksp.KspExperimental +import com.google.devtools.ksp.processing.Dependencies +import com.google.devtools.ksp.processing.Resolver +import com.google.devtools.ksp.processing.SymbolProcessor +import com.google.devtools.ksp.processing.SymbolProcessorEnvironment +import com.google.devtools.ksp.symbol.ClassKind +import com.google.devtools.ksp.symbol.KSAnnotated +import com.google.devtools.ksp.symbol.KSClassDeclaration +import dev.slne.surf.api.processor.ClassNames +import dev.slne.surf.api.processor.util.AnnotationUtils +import dev.slne.surf.api.processor.util.getArgumentValueAs +import dev.slne.surf.api.processor.util.toBinaryName +import dev.slne.surf.api.shared.internal.nms.NmsProviderConfig +import dev.slne.surf.api.shared.internal.nms.NmsProviderMeta +import dev.slne.surf.api.shared.internal.nms.NmsVersion + +class NmsProvidersCollector(environment: SymbolProcessorEnvironment) : SymbolProcessor { + + private val logger = environment.logger + private val codeGenerator = environment.codeGenerator + private val nmsProviders = mutableMapOf>() + + @OptIn(KspExperimental::class) + override fun process(resolver: Resolver): List { + val metas = AnnotationUtils.findAnnotatedClasses( + resolver = resolver, + annotationFqName = ClassNames.NMS_PROVIDER, + includeMetaAnnotations = false, + excludeAnnotationClasses = false, + logger = logger + ).mapNotNull(fun(nmsProviderClass): NmsProviderMeta? { + val annotation = nmsProviderClass.findNmsProviderAnnotation() ?: return null + val rawVersion = annotation.getArgumentValueAs("version") ?: return null + if (rawVersion.classKind != ClassKind.ENUM_ENTRY) return null + + val version = try { + NmsVersion.valueOf(rawVersion.simpleName.asString()) + } catch (_: Throwable) { + logger.error("Unknown NmsVersion: ${rawVersion.simpleName.asString()}") + return null + } + + return NmsProviderMeta(version, nmsProviderClass.toBinaryName()) + }).toList() + + val module = resolver.getModuleName().asString() + nmsProviders.computeIfAbsent(module) { mutableListOf() }.addAll(metas) + + return emptyList() + } + + private fun KSAnnotated.findNmsProviderAnnotation() = annotations.find { + it.annotationType.resolve().declaration.qualifiedName?.asString() == ClassNames.NMS_PROVIDER + } + + override fun finish() { + for ((module, providers) in nmsProviders) { + if (providers.isEmpty()) continue + + val filePath = "${NmsProviderConfig.NMS_PROVIDERS_DIRECTORY}/$module.json" + try { + codeGenerator.createNewFileByPath(Dependencies.ALL_FILES, filePath, "") + .bufferedWriter() + .use { writer -> + val jsonString = NmsProviderConfig.json.encodeToString(providers) + writer.write(jsonString) + } + + logger.info("Wrote NMS providers to: $filePath") + } catch (e: Exception) { + logger.error("Unable to create $filePath, $e") + } + } + + nmsProviders.clear() + } +} \ No newline at end of file diff --git a/surf-api-gradle-plugin/surf-api-processor/src/main/kotlin/dev/slne/surf/api/processor/nms/NmsProvidersCollectorProvider.kt b/surf-api-gradle-plugin/surf-api-processor/src/main/kotlin/dev/slne/surf/api/processor/nms/NmsProvidersCollectorProvider.kt new file mode 100644 index 000000000..d4b0895ad --- /dev/null +++ b/surf-api-gradle-plugin/surf-api-processor/src/main/kotlin/dev/slne/surf/api/processor/nms/NmsProvidersCollectorProvider.kt @@ -0,0 +1,11 @@ +package dev.slne.surf.api.processor.nms + +import com.google.devtools.ksp.processing.SymbolProcessor +import com.google.devtools.ksp.processing.SymbolProcessorEnvironment +import com.google.devtools.ksp.processing.SymbolProcessorProvider + +class NmsProvidersCollectorProvider : SymbolProcessorProvider { + override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { + return NmsProvidersCollector(environment) + } +} \ No newline at end of file diff --git a/surf-api-gradle-plugin/surf-api-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider b/surf-api-gradle-plugin/surf-api-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider index 213861160..8bbb4d91d 100644 --- a/surf-api-gradle-plugin/surf-api-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider +++ b/surf-api-gradle-plugin/surf-api-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider @@ -1,2 +1,3 @@ dev.slne.surf.api.processor.autoservice.AutoServiceSymbolProcessorProvider -dev.slne.surf.api.processor.component.ComponentSymbolProcessorProvider \ No newline at end of file +dev.slne.surf.api.processor.nms.NmsProvidersCollectorProvider +dev.slne.surf.api.processor.component.ComponentSymbolProcessorProvider diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/build.gradle.kts b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/build.gradle.kts index 93151e44f..583bc237c 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/build.gradle.kts +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/build.gradle.kts @@ -4,5 +4,6 @@ plugins { dependencies { compileOnlyApi(projects.surfApiPaper.surfApiPaper) + compileOnlyApi(projects.surfApiShared.surfApiSharedInternal) compileOnly(libs.paper.api) } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/AbstractChannelInjector.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/AbstractChannelInjector.kt index bcb90649e..5fd307cdb 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/AbstractChannelInjector.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/AbstractChannelInjector.kt @@ -13,7 +13,6 @@ import io.netty.util.AttributeKey import net.kyori.adventure.key.Key import org.bukkit.entity.Player import org.bukkit.event.Listener -import org.bukkit.plugin.Plugin import dev.slne.surf.api.paper.event.register as registerListener import dev.slne.surf.api.paper.event.unregister as unregisterListener @@ -30,14 +29,9 @@ abstract class AbstractChannelInjector("surf_api_packet_handler") - /** - * The plugin instance used for listener registration. - */ - protected abstract val plugin: Plugin - fun register() { registerChannelInitializeListener(CHANNEL_KEY) { this.getOrInjectPacketHandler(it) } - registerListener(plugin) + registerListener(NmsProvider.current.plugin) } fun unregister() { diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt index bac279a79..6eb027027 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt @@ -14,15 +14,19 @@ import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToas import dev.slne.surf.api.paper.packet.listener.SurfPaperPacketListenerApi import dev.slne.surf.api.paper.packet.listener.listener.PacketListener import dev.slne.surf.api.paper.region.TickThreadGuard -import java.util.* +import dev.slne.surf.api.shared.internal.nms.NmsProviderConfig +import dev.slne.surf.api.shared.internal.nms.NmsProviderMeta +import dev.slne.surf.api.shared.internal.nms.NmsVersion +import org.bukkit.plugin.java.JavaPlugin +import java.io.File +import java.net.URI +import java.util.jar.JarFile /** * Main interface for version-specific NMS operations. * * Each supported Minecraft version provides an implementation of this interface * that creates the appropriate NMS bridge implementations and packet listeners. - * - * Implementations are discovered at runtime using [java.util.ServiceLoader]. */ @NmsUseWithCaution interface NmsProvider { @@ -30,6 +34,7 @@ interface NmsProvider { * The NMS version this provider supports. */ val version: NmsVersion + val plugin: JavaPlugin // ==================== Bridge Factories ==================== // @@ -106,37 +111,87 @@ interface NmsProvider { * @throws IllegalStateException if no provider is found for the current version */ val current: NmsProvider by lazy { - val version = NmsVersion.current - val loader = ServiceLoader.load(NmsProvider::class.java) - val providers = mutableListOf() - - val iterator = loader.iterator() - while (iterator.hasNext()) { - val instance: NmsProvider? - try { - instance = iterator.next() - } catch (_: ServiceConfigurationError) { - continue + val version = NmsVersionResolver.current + + try { + val metas = mutableListOf() + + val resources = javaClass.classLoader.getResources(NmsProviderConfig.NMS_PROVIDERS_DIRECTORY) + while (resources.hasMoreElements()) { + val url = resources.nextElement() + + if (url.protocol == "jar") { + val jarPath = url.path.substringBefore("!") + JarFile(File(URI(jarPath))).use { jarFile -> + jarFile.entries().asSequence() + .filter { + it.name.startsWith(NmsProviderConfig.NMS_PROVIDERS_DIRECTORY) && it.name.endsWith( + ".json" + ) + } + .forEach { entry -> + try { + val raw = jarFile.getInputStream(entry).bufferedReader() + .use { it.readText() } + val decoded = + NmsProviderConfig.json.decodeFromString>(raw) + metas += decoded + } catch (e: Exception) { + log.atSevere() + .withCause(e) + .log("Failed to parse ${entry.name}") + } + } + } + } else { + val dir = File(url.toURI()) + dir.listFiles { file -> file.extension == "json" }?.forEach { file -> + try { + val raw = file.readText() + val decoded = + NmsProviderConfig.json.decodeFromString>(raw) + metas += decoded + } catch (e: Exception) { + log.atSevere() + .withCause(e) + .log("Failed to parse ${file.name}") + } + } + } + } + + log.atInfo().log("Discovered %s NmsProviders: %s", metas.size, metas.joinToString(", ")) + + val selectedMeta = metas.find { it.version == version }?.also { meta -> + log.atInfo().log("Found matching NmsProvider: %s", meta.version.versionPrefix) + } ?: run { + log.atWarning() + .log("No exact match for NmsProvider version %s, using fallback", version.versionPrefix) + val fallback = metas.maxByOrNull { it.version.versionPrefix } + ?: error("No NmsProvider implementations found") + log.atWarning().log("Selected fallback NmsProvider: %s", fallback.version.versionPrefix) + fallback + } + + val clazz = try { + Class.forName(selectedMeta.implementation) + } catch (e: Throwable) { + throw IllegalStateException("Failed to load NmsProvider implementation", e) + } + + val constructor = try { + clazz.getConstructor(JavaPlugin::class.java) + } catch (e: Throwable) { + throw IllegalStateException( + "Failed to load NmsProvider implementation. Implementation must have a constructor with a single argument of type JavaPlugin", + e + ) } - providers.add(instance) - } - log.atInfo().log("Looking for NmsProvider with version: %s", version) - log.atInfo().log( - "Available NmsProviders: %s", - providers.joinToString(", ") { "${it.version.name} (${it.version.versionPrefix})" }) - - val matched = providers.firstOrNull { it.version == version } - if (matched != null) { - log.atInfo().log("Found matching NmsProvider: %s", matched.version.name) - matched - } else { - log.atWarning() - .log("No exact match for NmsProvider version %s, using fallback", version) - val fallback = providers.maxByOrNull { it.version.versionPrefix } - ?: error("No NmsProvider implementations found") - log.atWarning().log("Selected fallback NmsProvider: %s", fallback.version.name) - fallback + constructor.newInstance(JavaPlugin.getProvidingPlugin(NmsProvider::class.java)) as NmsProvider + } catch (e: Exception) { + log.atSevere().withCause(e).log("Failed to load NmsProvider") + throw IllegalStateException("Failed to load NmsProvider", e) } } } diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersion.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersion.kt deleted file mode 100644 index c2c1e5994..000000000 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersion.kt +++ /dev/null @@ -1,40 +0,0 @@ -package dev.slne.surf.api.paper.nms.common - -import dev.slne.surf.api.core.util.logger -import org.bukkit.Bukkit - -/** - * Represents the supported Minecraft NMS versions. - * - * @property versionPrefix The version prefix used to match `Bukkit.getMinecraftVersion()`. - */ -enum class NmsVersion(val versionPrefix: String) { - V1_21_11("1.21.11"), - V26_1("26.1"); - - companion object { - private val log = logger() - - /** - * The NMS version of the currently running Minecraft server. - * - * Detected at runtime from `Bukkit.getMinecraftVersion()`. - * Uses latest provided NMS version if no exact match is found. - */ - val current: NmsVersion by lazy { - val mcVersion = Bukkit.getMinecraftVersion() - val matched = entries.firstOrNull { mcVersion.startsWith(it.versionPrefix) } - if (matched != null) { - matched - } else { - val fallback = - entries.maxByOrNull { it.versionPrefix } ?: error("No NMS versions defined!") - log.atWarning().log( - "There is no matching nms version, using fallback NMS version: %s", - fallback.name - ) - fallback - } - } - } -} diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersionResolver.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersionResolver.kt new file mode 100644 index 000000000..a4584e080 --- /dev/null +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsVersionResolver.kt @@ -0,0 +1,30 @@ +package dev.slne.surf.api.paper.nms.common + +import dev.slne.surf.api.core.util.logger +import dev.slne.surf.api.shared.internal.nms.NmsVersion +import org.bukkit.Bukkit + +object NmsVersionResolver { + private val log = logger() + + /** + * The NMS version of the currently running Minecraft server. + * + * Detected at runtime from `Bukkit.getMinecraftVersion()`. + * Uses latest provided NMS version if no exact match is found. + */ + val current: NmsVersion by lazy { + val mcVersion = Bukkit.getMinecraftVersion() + val matched = NmsVersion.entries.firstOrNull { mcVersion.startsWith(it.versionPrefix) } + if (matched != null) { + matched + } else { + val fallback = NmsVersion.entries.maxByOrNull { it.versionPrefix } ?: error("No NMS versions defined!") + log.atWarning().log( + "There is no matching nms version, using fallback NMS version: %s", + fallback.name + ) + fallback + } + } +} \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt index 901ba123b..4debd12df 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt @@ -1,6 +1,5 @@ package dev.slne.surf.api.paper.server.nms.v1_21_11 -import com.google.auto.service.AutoService import dev.slne.surf.api.paper.glow.SurfGlowingApi import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge @@ -30,10 +29,14 @@ import dev.slne.surf.api.paper.server.nms.v1_21_11.packet.lore.V1_21_11PacketLor import dev.slne.surf.api.paper.server.nms.v1_21_11.packet.lore.V1_21_11PacketLoreRegistry import dev.slne.surf.api.paper.server.nms.v1_21_11.reflection.V1_21_11Reflection import dev.slne.surf.api.paper.server.nms.v1_21_11.region.V1_21_11TickThreadGuard +import dev.slne.surf.api.shared.internal.nms.NmsProviderMarker +import dev.slne.surf.api.shared.internal.nms.NmsVersion +import org.bukkit.plugin.java.JavaPlugin +@Suppress("ClassName") @OptIn(NmsUseWithCaution::class) -@AutoService(NmsProvider::class) -class V1_21_11NmsProvider : NmsProvider { +@NmsProviderMarker(NmsVersion.V1_21_11) +class V1_21_11NmsProvider(override val plugin: JavaPlugin) : NmsProvider { override val version: NmsVersion = NmsVersion.V1_21_11 override fun createNmsBridge(): SurfPaperNmsBridge = V1_21_11SurfPaperNmsBridgeImpl() diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11PacketListenerApiImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11PacketListenerApiImpl.kt index d0568e9c8..8ff01d075 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11PacketListenerApiImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11PacketListenerApiImpl.kt @@ -1,6 +1,5 @@ package dev.slne.surf.api.paper.server.nms.v1_21_11.bridges -import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader import dev.slne.surf.api.core.util.logger import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.common.InternalPacketListenerApiBridge @@ -48,10 +47,6 @@ class V1_21_11PacketListenerApiImpl : InternalPacketListenerApiBridge { fun toBukkitPlayer(serverPlayer: ServerPlayer?): Player? = serverPlayer?.bukkitEntity } - init { - checkInstantiationByServiceLoader() - } - override fun registerListeners(listener: PacketListener) { for (method in listener.javaClass.declaredMethods) { try { diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11SurfGlowingApiImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11SurfGlowingApiImpl.kt index a026f8b9b..344f82e33 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11SurfGlowingApiImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/glow/V1_21_11SurfGlowingApiImpl.kt @@ -6,6 +6,7 @@ import dev.slne.surf.api.paper.extensions.server import dev.slne.surf.api.paper.glow.SurfGlowingApi import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation +import dev.slne.surf.api.paper.nms.common.NmsProvider import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.V1_21_11SurfPaperNmsGlowingBridgeImpl import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.block.BlockGlowingData import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.block.BlockPlayerData @@ -19,7 +20,6 @@ import org.bukkit.Location import org.bukkit.block.Block import org.bukkit.entity.Entity import org.bukkit.entity.Player -import org.bukkit.plugin.java.JavaPlugin import java.util.* import java.util.concurrent.ConcurrentHashMap @@ -102,7 +102,7 @@ object V1_21_11SurfGlowingApiImpl : SurfGlowingApi { val newData = BlockGlowingData(playerData, blockLocation, color) playerData.blocks[blockLocation] = newData - val plugin = JavaPlugin.getProvidingPlugin(javaClass) + val plugin = NmsProvider.current.plugin plugin.launch(plugin.entityDispatcher(viewer)) { if (viewer.isChunkVisible(blockLocation)) { newData.spawn().execute(viewer) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/listener/V1_21_11ChannelInjector.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/listener/V1_21_11ChannelInjector.kt index 8edb32478..86cfd5fa9 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/listener/V1_21_11ChannelInjector.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/packet/listener/V1_21_11ChannelInjector.kt @@ -21,15 +21,11 @@ import org.bukkit.entity.Player import org.bukkit.event.EventHandler import org.bukkit.event.EventPriority import org.bukkit.event.player.PlayerJoinEvent -import org.bukkit.plugin.Plugin -import org.bukkit.plugin.java.JavaPlugin @Suppress("ClassName", "UnstableApiUsage") object V1_21_11ChannelInjector : AbstractChannelInjector() { private val log = logger() - override val plugin: Plugin get() = JavaPlugin.getProvidingPlugin(V1_21_11ChannelInjector::class.java) - override fun registerChannelInitializeListener( key: Key, listener: (Channel) -> Unit diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt index 8754825f7..e82c88eef 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt @@ -1,6 +1,5 @@ package dev.slne.surf.api.paper.server.nms.v26_1 -import com.google.auto.service.AutoService import dev.slne.surf.api.paper.glow.SurfGlowingApi import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge @@ -30,11 +29,14 @@ import dev.slne.surf.api.paper.server.nms.v26_1.packet.lore.V26_1PacketLoreListe import dev.slne.surf.api.paper.server.nms.v26_1.packet.lore.V26_1PacketLoreRegistry import dev.slne.surf.api.paper.server.nms.v26_1.reflection.V26_1Reflection import dev.slne.surf.api.paper.server.nms.v26_1.region.V26_1TickThreadGuard +import dev.slne.surf.api.shared.internal.nms.NmsProviderMarker +import dev.slne.surf.api.shared.internal.nms.NmsVersion +import org.bukkit.plugin.java.JavaPlugin @Suppress("ClassName") @OptIn(NmsUseWithCaution::class) -@AutoService(NmsProvider::class) -class V26_1NmsProvider : NmsProvider { +@NmsProviderMarker(NmsVersion.V26_1) +class V26_1NmsProvider(override val plugin: JavaPlugin) : NmsProvider { override val version: NmsVersion = NmsVersion.V26_1 override fun createNmsBridge(): SurfPaperNmsBridge = V26_1SurfPaperNmsBridgeImpl() diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1PacketListenerApiImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1PacketListenerApiImpl.kt index 1c407881d..88794c40f 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1PacketListenerApiImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1PacketListenerApiImpl.kt @@ -1,6 +1,5 @@ package dev.slne.surf.api.paper.server.nms.v26_1.bridges -import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader import dev.slne.surf.api.core.util.logger import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.common.InternalPacketListenerApiBridge @@ -48,10 +47,6 @@ class V26_1PacketListenerApiImpl : InternalPacketListenerApiBridge { fun toBukkitPlayer(serverPlayer: ServerPlayer?): Player? = serverPlayer?.bukkitEntity } - init { - checkInstantiationByServiceLoader() - } - override fun registerListeners(listener: PacketListener) { for (method in listener.javaClass.declaredMethods) { try { diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt index 07c3fbf47..4a73bcfa8 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/glow/V26_1SurfGlowingApiImpl.kt @@ -6,6 +6,7 @@ import dev.slne.surf.api.paper.extensions.server import dev.slne.surf.api.paper.glow.SurfGlowingApi import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.bridges.packets.PacketOperation +import dev.slne.surf.api.paper.nms.common.NmsProvider import dev.slne.surf.api.paper.server.nms.v26_1.bridges.V26_1SurfPaperNmsGlowingBridgeImpl import dev.slne.surf.api.paper.server.nms.v26_1.glow.block.BlockGlowingData import dev.slne.surf.api.paper.server.nms.v26_1.glow.block.BlockPlayerData @@ -19,7 +20,6 @@ import org.bukkit.Location import org.bukkit.block.Block import org.bukkit.entity.Entity import org.bukkit.entity.Player -import org.bukkit.plugin.java.JavaPlugin import java.util.* import java.util.concurrent.ConcurrentHashMap @@ -103,7 +103,7 @@ object V26_1SurfGlowingApiImpl : SurfGlowingApi { val newData = BlockGlowingData(playerData, blockLocation, color) playerData.blocks[blockLocation] = newData - val plugin = JavaPlugin.getProvidingPlugin(javaClass) + val plugin = NmsProvider.current.plugin plugin.launch(plugin.entityDispatcher(viewer)) { if (viewer.isChunkVisible(blockLocation)) { newData.spawn().execute(viewer) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1ChannelInjector.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1ChannelInjector.kt index 072fbe219..4d9be3043 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1ChannelInjector.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/packet/listener/V26_1ChannelInjector.kt @@ -21,15 +21,11 @@ import org.bukkit.entity.Player import org.bukkit.event.EventHandler import org.bukkit.event.EventPriority import org.bukkit.event.player.PlayerJoinEvent -import org.bukkit.plugin.Plugin -import org.bukkit.plugin.java.JavaPlugin @Suppress("ClassName", "UnstableApiUsage") object V26_1ChannelInjector : AbstractChannelInjector() { private val log = logger() - override val plugin: Plugin get() = JavaPlugin.getProvidingPlugin(V26_1ChannelInjector::class.java) - override fun registerChannelInitializeListener( key: Key, listener: (Channel) -> Unit diff --git a/surf-api-shared/surf-api-shared-internal/src/main/kotlin/dev/slne/surf/api/shared/internal/nms/NmsProviderConfig.kt b/surf-api-shared/surf-api-shared-internal/src/main/kotlin/dev/slne/surf/api/shared/internal/nms/NmsProviderConfig.kt new file mode 100644 index 000000000..3e05f21b2 --- /dev/null +++ b/surf-api-shared/surf-api-shared-internal/src/main/kotlin/dev/slne/surf/api/shared/internal/nms/NmsProviderConfig.kt @@ -0,0 +1,12 @@ +package dev.slne.surf.api.shared.internal.nms + +import kotlinx.serialization.json.Json + +object NmsProviderConfig { + const val NMS_PROVIDERS_DIRECTORY = "META-INF/surf-api/nms-providers" + val json = Json { + prettyPrint = true + ignoreUnknownKeys = true + prettyPrintIndent = " " + } +} \ No newline at end of file diff --git a/surf-api-shared/surf-api-shared-internal/src/main/kotlin/dev/slne/surf/api/shared/internal/nms/NmsProviderMarker.kt b/surf-api-shared/surf-api-shared-internal/src/main/kotlin/dev/slne/surf/api/shared/internal/nms/NmsProviderMarker.kt new file mode 100644 index 000000000..5a73dc19d --- /dev/null +++ b/surf-api-shared/surf-api-shared-internal/src/main/kotlin/dev/slne/surf/api/shared/internal/nms/NmsProviderMarker.kt @@ -0,0 +1,5 @@ +package dev.slne.surf.api.shared.internal.nms + +@Retention(AnnotationRetention.RUNTIME) +@Target(AnnotationTarget.CLASS) +annotation class NmsProviderMarker(val version: NmsVersion) diff --git a/surf-api-shared/surf-api-shared-internal/src/main/kotlin/dev/slne/surf/api/shared/internal/nms/NmsProviderMeta.kt b/surf-api-shared/surf-api-shared-internal/src/main/kotlin/dev/slne/surf/api/shared/internal/nms/NmsProviderMeta.kt new file mode 100644 index 000000000..4d07c513f --- /dev/null +++ b/surf-api-shared/surf-api-shared-internal/src/main/kotlin/dev/slne/surf/api/shared/internal/nms/NmsProviderMeta.kt @@ -0,0 +1,9 @@ +package dev.slne.surf.api.shared.internal.nms + +import kotlinx.serialization.Serializable + +@Serializable +data class NmsProviderMeta( + val version: NmsVersion, + val implementation: String +) \ No newline at end of file diff --git a/surf-api-shared/surf-api-shared-internal/src/main/kotlin/dev/slne/surf/api/shared/internal/nms/NmsVersion.kt b/surf-api-shared/surf-api-shared-internal/src/main/kotlin/dev/slne/surf/api/shared/internal/nms/NmsVersion.kt new file mode 100644 index 000000000..7c6f0a6db --- /dev/null +++ b/surf-api-shared/surf-api-shared-internal/src/main/kotlin/dev/slne/surf/api/shared/internal/nms/NmsVersion.kt @@ -0,0 +1,11 @@ +package dev.slne.surf.api.shared.internal.nms + +/** + * Represents the supported Minecraft NMS versions. + * + * @property versionPrefix The version prefix used to match `Bukkit.getMinecraftVersion()`. + */ +enum class NmsVersion(val versionPrefix: String) { + V1_21_11("1.21.11"), + V26_1("26.1"); +} \ No newline at end of file From 1383bfaffb4a245fb6fd5d1c973277c136405e63 Mon Sep 17 00:00:00 2001 From: twisti <76837088+twisti-dev@users.noreply.github.com> Date: Thu, 16 Apr 2026 18:21:33 +0200 Subject: [PATCH 27/34] =?UTF-8?q?=E2=9C=A8=20feat(nms):=20update=20NmsBrid?= =?UTF-8?q?ge=20implementation=20for=20multiversion=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - rename SurfPaperNmsBridge to InternalNmsBridge for clarity - adjust createNmsBridge method to return appropriate bridge implementations --- .../dev/slne/surf/api/paper/nms/common/NmsProvider.kt | 3 +-- .../api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt | 3 +-- .../v1_21_11/bridges/V1_21_11SurfPaperNmsBridgeImpl.kt | 8 ++++---- .../surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt | 3 +-- .../nms/v26_1/bridges/V26_1SurfPaperNmsBridgeImpl.kt | 8 ++++---- 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt index 6eb027027..6863ab8ca 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt @@ -3,7 +3,6 @@ package dev.slne.surf.api.paper.nms.common import dev.slne.surf.api.core.util.logger import dev.slne.surf.api.paper.glow.SurfGlowingApi import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge import dev.slne.surf.api.paper.nms.bridges.* import dev.slne.surf.api.paper.nms.bridges.packets.SurfPaperNmsPacketBridges import dev.slne.surf.api.paper.nms.bridges.packets.block.SurfPaperNmsBlockPackets @@ -38,7 +37,7 @@ interface NmsProvider { // ==================== Bridge Factories ==================== // - fun createNmsBridge(): SurfPaperNmsBridge + fun createNmsBridge(): InternalNmsBridge fun createCommonBridge(): SurfPaperNmsCommonBridge fun createEntityBridge(): SurfPaperNmsEntityBridge fun createItemBridge(): SurfPaperNmsItemBridge diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt index 4debd12df..281ad6fc1 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt @@ -2,7 +2,6 @@ package dev.slne.surf.api.paper.server.nms.v1_21_11 import dev.slne.surf.api.paper.glow.SurfGlowingApi import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge import dev.slne.surf.api.paper.nms.bridges.* import dev.slne.surf.api.paper.nms.bridges.packets.SurfPaperNmsPacketBridges import dev.slne.surf.api.paper.nms.bridges.packets.block.SurfPaperNmsBlockPackets @@ -39,7 +38,7 @@ import org.bukkit.plugin.java.JavaPlugin class V1_21_11NmsProvider(override val plugin: JavaPlugin) : NmsProvider { override val version: NmsVersion = NmsVersion.V1_21_11 - override fun createNmsBridge(): SurfPaperNmsBridge = V1_21_11SurfPaperNmsBridgeImpl() + override fun createNmsBridge() = V1_21_11SurfPaperNmsBridgeImpl() override fun createCommonBridge(): SurfPaperNmsCommonBridge = V1_21_11SurfPaperNmsCommonBridgeImpl() diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsBridgeImpl.kt index 7798c93a3..2f94281a0 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/bridges/V1_21_11SurfPaperNmsBridgeImpl.kt @@ -5,7 +5,7 @@ import dev.slne.surf.api.core.util.logger import dev.slne.surf.api.paper.api.nms.listener.NmsClientboundPacketListener import dev.slne.surf.api.paper.api.nms.listener.NmsServerboundPacketListener import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge +import dev.slne.surf.api.paper.nms.common.InternalNmsBridge import dev.slne.surf.api.paper.nms.listener.packets.clientbound.NmsClientboundPacket import dev.slne.surf.api.paper.nms.listener.packets.serverbound.NmsServerboundPacket import dev.slne.surf.api.paper.packet.listener.listener.PacketListenerResult @@ -14,7 +14,7 @@ import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.CopyOnWriteArraySet @NmsUseWithCaution -class V1_21_11SurfPaperNmsBridgeImpl : SurfPaperNmsBridge { +class V1_21_11SurfPaperNmsBridgeImpl : InternalNmsBridge { private typealias PacketListenerMap = ConcurrentHashMap, CopyOnWriteArraySet> private val log = logger() @@ -69,7 +69,7 @@ class V1_21_11SurfPaperNmsBridgeImpl : SurfPaperNmsBridge { } @Suppress("UNCHECKED_CAST") - fun handleServerboundPacket( + override fun handleServerboundPacket( packet: Packet, player: Player?, ): Packet? { @@ -97,7 +97,7 @@ class V1_21_11SurfPaperNmsBridgeImpl : SurfPaperNmsBridge { } @Suppress("UNCHECKED_CAST") - fun handleClientboundPacket( + override fun handleClientboundPacket( packet: Packet, player: Player?, ): Packet? { diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt index e82c88eef..1b1d32e30 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt @@ -2,7 +2,6 @@ package dev.slne.surf.api.paper.server.nms.v26_1 import dev.slne.surf.api.paper.glow.SurfGlowingApi import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge import dev.slne.surf.api.paper.nms.bridges.* import dev.slne.surf.api.paper.nms.bridges.packets.SurfPaperNmsPacketBridges import dev.slne.surf.api.paper.nms.bridges.packets.block.SurfPaperNmsBlockPackets @@ -39,7 +38,7 @@ import org.bukkit.plugin.java.JavaPlugin class V26_1NmsProvider(override val plugin: JavaPlugin) : NmsProvider { override val version: NmsVersion = NmsVersion.V26_1 - override fun createNmsBridge(): SurfPaperNmsBridge = V26_1SurfPaperNmsBridgeImpl() + override fun createNmsBridge() = V26_1SurfPaperNmsBridgeImpl() override fun createCommonBridge(): SurfPaperNmsCommonBridge = V26_1SurfPaperNmsCommonBridgeImpl() diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsBridgeImpl.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsBridgeImpl.kt index 030a684b6..e982c2691 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsBridgeImpl.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/bridges/V26_1SurfPaperNmsBridgeImpl.kt @@ -5,7 +5,7 @@ import dev.slne.surf.api.core.util.logger import dev.slne.surf.api.paper.api.nms.listener.NmsClientboundPacketListener import dev.slne.surf.api.paper.api.nms.listener.NmsServerboundPacketListener import dev.slne.surf.api.paper.nms.NmsUseWithCaution -import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge +import dev.slne.surf.api.paper.nms.common.InternalNmsBridge import dev.slne.surf.api.paper.nms.listener.packets.clientbound.NmsClientboundPacket import dev.slne.surf.api.paper.nms.listener.packets.serverbound.NmsServerboundPacket import dev.slne.surf.api.paper.packet.listener.listener.PacketListenerResult @@ -15,7 +15,7 @@ import java.util.concurrent.CopyOnWriteArraySet @NmsUseWithCaution @Suppress("ClassName") -class V26_1SurfPaperNmsBridgeImpl : SurfPaperNmsBridge { +class V26_1SurfPaperNmsBridgeImpl : InternalNmsBridge { private typealias PacketListenerMap = ConcurrentHashMap, CopyOnWriteArraySet> private val log = logger() @@ -70,7 +70,7 @@ class V26_1SurfPaperNmsBridgeImpl : SurfPaperNmsBridge { } @Suppress("UNCHECKED_CAST") - fun handleServerboundPacket( + override fun handleServerboundPacket( packet: Packet, player: Player?, ): Packet? { @@ -98,7 +98,7 @@ class V26_1SurfPaperNmsBridgeImpl : SurfPaperNmsBridge { } @Suppress("UNCHECKED_CAST") - fun handleClientboundPacket( + override fun handleClientboundPacket( packet: Packet, player: Player?, ): Packet? { From a7d1c1f059bfe5e8f57f40d837514f425aa7f23f Mon Sep 17 00:00:00 2001 From: twisti <76837088+twisti-dev@users.noreply.github.com> Date: Thu, 16 Apr 2026 18:24:07 +0200 Subject: [PATCH 28/34] =?UTF-8?q?=E2=9C=A8=20feat(nms):=20update=20SurfPap?= =?UTF-8?q?erNmsBridgeProxy=20to=20use=20InternalNmsBridge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - change implementation from NmsBridge to InternalNmsBridge for better multiversion support --- .../surf/api/paper/server/proxy/SurfPaperNmsBridgeProxy.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsBridgeProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsBridgeProxy.kt index 20b49f916..4faebd1de 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsBridgeProxy.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperNmsBridgeProxy.kt @@ -4,11 +4,12 @@ import com.google.auto.service.AutoService import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader import dev.slne.surf.api.paper.nms.NmsUseWithCaution import dev.slne.surf.api.paper.nms.SurfPaperNmsBridge +import dev.slne.surf.api.paper.nms.common.InternalNmsBridge import dev.slne.surf.api.paper.nms.common.NmsProvider @NmsUseWithCaution @AutoService(SurfPaperNmsBridge::class) -class SurfPaperNmsBridgeProxy : SurfPaperNmsBridge by NmsProvider.current.createNmsBridge() { +class SurfPaperNmsBridgeProxy : InternalNmsBridge by NmsProvider.current.createNmsBridge() { init { checkInstantiationByServiceLoader() } From 55e7a4706d3013b8cbcbe1342348f18f33a654bc Mon Sep 17 00:00:00 2001 From: twisti <76837088+twisti-dev@users.noreply.github.com> Date: Thu, 16 Apr 2026 18:25:42 +0200 Subject: [PATCH 29/34] =?UTF-8?q?=E2=9C=A8=20feat(nms):=20update=20packet?= =?UTF-8?q?=20listener=20API=20to=20use=20InternalPacketListenerApiBridge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - change createPacketListenerApi return type to InternalPacketListenerApiBridge - update SurfPaperPacketListenerApiProxy to implement InternalPacketListenerApiBridge - modify version-specific NmsProvider implementations to return InternalPacketListenerApiBridge --- .../kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt | 3 +-- .../surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt | 3 +-- .../slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt | 3 +-- .../api/paper/server/proxy/SurfPaperPacketListenerApiProxy.kt | 3 ++- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt index 6863ab8ca..34f339a92 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt @@ -10,7 +10,6 @@ import dev.slne.surf.api.paper.nms.bridges.packets.entity.SurfPaperNmsSpawnPacke import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerChatPackets import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerPackets import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToastPackets -import dev.slne.surf.api.paper.packet.listener.SurfPaperPacketListenerApi import dev.slne.surf.api.paper.packet.listener.listener.PacketListener import dev.slne.surf.api.paper.region.TickThreadGuard import dev.slne.surf.api.shared.internal.nms.NmsProviderConfig @@ -82,7 +81,7 @@ interface NmsProvider { // ==================== Packet Listeners ==================== // fun createChannelInjector(): AbstractChannelInjector<*> - fun createPacketListenerApi(): SurfPaperPacketListenerApi + fun createPacketListenerApi(): InternalPacketListenerApiBridge /** * Creates version-specific packet listeners (e.g. lore handler, glowing handler). diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt index 281ad6fc1..8f1f27b06 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v1-21-11/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v1_21_11/V1_21_11NmsProvider.kt @@ -10,7 +10,6 @@ import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerChat import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerPackets import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToastPackets import dev.slne.surf.api.paper.nms.common.* -import dev.slne.surf.api.paper.packet.listener.SurfPaperPacketListenerApi import dev.slne.surf.api.paper.packet.listener.listener.PacketListener import dev.slne.surf.api.paper.region.TickThreadGuard import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.* @@ -87,7 +86,7 @@ class V1_21_11NmsProvider(override val plugin: JavaPlugin) : NmsProvider { override fun createGlowingApi(): SurfGlowingApi = V1_21_11SurfGlowingApiImpl override fun createChannelInjector(): AbstractChannelInjector<*> = V1_21_11ChannelInjector - override fun createPacketListenerApi(): SurfPaperPacketListenerApi = V1_21_11PacketListenerApiImpl() + override fun createPacketListenerApi(): InternalPacketListenerApiBridge = V1_21_11PacketListenerApiImpl() override fun createPacketListeners(): List = listOf( V1_21_11PacketLoreListener, diff --git a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt index 1b1d32e30..9d228478f 100644 --- a/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt +++ b/surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-v26-1/src/main/kotlin/dev/slne/surf/api/paper/server/nms/v26_1/V26_1NmsProvider.kt @@ -10,7 +10,6 @@ import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerChat import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerPackets import dev.slne.surf.api.paper.nms.bridges.packets.player.SurfPaperNmsPlayerToastPackets import dev.slne.surf.api.paper.nms.common.* -import dev.slne.surf.api.paper.packet.listener.SurfPaperPacketListenerApi import dev.slne.surf.api.paper.packet.listener.listener.PacketListener import dev.slne.surf.api.paper.region.TickThreadGuard import dev.slne.surf.api.paper.server.nms.v26_1.bridges.* @@ -87,7 +86,7 @@ class V26_1NmsProvider(override val plugin: JavaPlugin) : NmsProvider { override fun createGlowingApi(): SurfGlowingApi = V26_1SurfGlowingApiImpl override fun createChannelInjector(): AbstractChannelInjector<*> = V26_1ChannelInjector - override fun createPacketListenerApi(): SurfPaperPacketListenerApi = V26_1PacketListenerApiImpl() + override fun createPacketListenerApi(): InternalPacketListenerApiBridge = V26_1PacketListenerApiImpl() override fun createPacketListeners(): List = listOf( V26_1PacketLoreListener, diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperPacketListenerApiProxy.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperPacketListenerApiProxy.kt index cdb0e3ac9..30d7b77ca 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperPacketListenerApiProxy.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/proxy/SurfPaperPacketListenerApiProxy.kt @@ -3,12 +3,13 @@ package dev.slne.surf.api.paper.server.proxy import com.google.auto.service.AutoService import dev.slne.surf.api.core.util.checkInstantiationByServiceLoader import dev.slne.surf.api.paper.nms.NmsUseWithCaution +import dev.slne.surf.api.paper.nms.common.InternalPacketListenerApiBridge import dev.slne.surf.api.paper.nms.common.NmsProvider import dev.slne.surf.api.paper.packet.listener.SurfPaperPacketListenerApi @NmsUseWithCaution @AutoService(SurfPaperPacketListenerApi::class) -class SurfPaperPacketListenerApiProxy : SurfPaperPacketListenerApi by NmsProvider.current.createPacketListenerApi() { +class SurfPaperPacketListenerApiProxy : InternalPacketListenerApiBridge by NmsProvider.current.createPacketListenerApi() { init { checkInstantiationByServiceLoader() } From 5c15de7be85abca1bdf3205b4204320f63e2db0f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 18 Apr 2026 14:43:36 +0000 Subject: [PATCH 30/34] chore: update ABI dumps for new LuckPerms and utility APIs Agent-Logs-Url: https://github.com/SLNE-Development/surf-api/sessions/3a0ffb0f-3b80-458c-bdd3-0594694f5cde Co-authored-by: twisti-dev <76837088+twisti-dev@users.noreply.github.com> --- surf-api-core/surf-api-core/api/surf-api-core.api | 15 +++++++++++++++ .../surf-api-paper/api/surf-api-paper.api | 4 ++++ .../surf-api-velocity/api/surf-api-velocity.api | 6 ++++++ 3 files changed, 25 insertions(+) diff --git a/surf-api-core/surf-api-core/api/surf-api-core.api b/surf-api-core/surf-api-core/api/surf-api-core.api index 6cb773d78..3d97d7481 100644 --- a/surf-api-core/surf-api-core/api/surf-api-core.api +++ b/surf-api-core/surf-api-core/api/surf-api-core.api @@ -6628,6 +6628,21 @@ public final class dev/slne/surf/api/core/invoker/SuspendInvokerSupport { public static synthetic fun invokeSuspendDirect$default (Ljava/lang/invoke/MethodHandle;Ljava/lang/Object;Lkotlin/coroutines/CoroutineContext;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; } +public final class dev/slne/surf/api/core/luckperms/LuckPermsAccess { + public static final field INSTANCE Ldev/slne/surf/api/core/luckperms/LuckPermsAccess; + public final fun getLuckperms ()Lnet/luckperms/api/LuckPerms; + public final fun getUser (Ljava/util/UUID;)Lnet/luckperms/api/model/user/User; + public final fun loadUser (Ljava/util/UUID;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + +public final class dev/slne/surf/api/core/luckperms/LuckPermsAccessKt { + public static final fun getLuckPermsUser (Lnet/kyori/adventure/audience/Audience;)Lnet/luckperms/api/model/user/User; + public static final fun getLuckPermsUserOrNull (Lnet/kyori/adventure/audience/Audience;)Lnet/luckperms/api/model/user/User; + public static final fun getPrefix (Lnet/luckperms/api/model/user/User;)Ljava/lang/String; + public static final fun getSuffix (Lnet/luckperms/api/model/user/User;)Ljava/lang/String; + public static final fun getWeight (Lnet/luckperms/api/model/user/User;)Ljava/lang/Object; +} + public final class dev/slne/surf/api/core/math/VoxelLineTracer { public static final field INSTANCE Ldev/slne/surf/api/core/math/VoxelLineTracer; public final fun trace (Lorg/spongepowered/math/vector/Vector3d;Lorg/spongepowered/math/vector/Vector3d;)Lkotlin/sequences/Sequence; diff --git a/surf-api-paper/surf-api-paper/api/surf-api-paper.api b/surf-api-paper/surf-api-paper/api/surf-api-paper.api index 20775881a..d9176dcf1 100644 --- a/surf-api-paper/surf-api-paper/api/surf-api-paper.api +++ b/surf-api-paper/surf-api-paper/api/surf-api-paper.api @@ -2286,6 +2286,10 @@ public final class dev/slne/surf/api/paper/util/UtilBukkit { public static final fun getChunkZ (Lio/papermc/paper/math/Position;)I public static final fun getChunkZ (Lorg/bukkit/Location;)I public static final fun getHighestBlockYAtBlockCoordinates (Lorg/bukkit/ChunkSnapshot;II)I + public static final fun getLuckPermsUser (Lorg/bukkit/OfflinePlayer;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static final fun getLuckPermsUser (Lorg/bukkit/entity/Player;)Lnet/luckperms/api/model/user/User; + public static final fun getLuckPermsUserOrNull (Lorg/bukkit/entity/Player;)Lnet/luckperms/api/model/user/User; + public static final fun getPrefixedName (Lorg/bukkit/entity/Player;)Lnet/kyori/adventure/text/Component; public static final fun getXFromChunkKey (J)I public static final fun getZFromChunkKey (J)I public static final fun isChunkVisible (Lorg/bukkit/entity/Player;Lorg/bukkit/Location;)Z diff --git a/surf-api-velocity/surf-api-velocity/api/surf-api-velocity.api b/surf-api-velocity/surf-api-velocity/api/surf-api-velocity.api index 31c58e6c9..d6c54c593 100644 --- a/surf-api-velocity/surf-api-velocity/api/surf-api-velocity.api +++ b/surf-api-velocity/surf-api-velocity/api/surf-api-velocity.api @@ -160,3 +160,9 @@ public final class dev/slne/surf/api/velocity/command/executors/SuspendCommandEx public static final fun sendSyntaxMessageOrRethrow (Lcom/velocitypowered/api/command/CommandSource;Ljava/lang/String;Ljava/lang/Throwable;)V } +public final class dev/slne/surf/api/velocity/util/Velocity_utilKt { + public static final fun getLuckPermsUser (Lcom/velocitypowered/api/proxy/Player;)Lnet/luckperms/api/model/user/User; + public static final fun getLuckPermsUserOrNull (Lcom/velocitypowered/api/proxy/Player;)Lnet/luckperms/api/model/user/User; + public static final fun getPrefixedName (Lcom/velocitypowered/api/proxy/Player;)Lnet/kyori/adventure/text/Component; +} + From ccc16ebb28c46b2de877dbf6ba4981a529d7936b Mon Sep 17 00:00:00 2001 From: twisti <76837088+twisti-dev@users.noreply.github.com> Date: Sat, 18 Apr 2026 20:00:03 +0200 Subject: [PATCH 31/34] Update surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/luckperms/LuckPermsAccess.kt Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../dev/slne/surf/api/core/luckperms/LuckPermsAccess.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/luckperms/LuckPermsAccess.kt b/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/luckperms/LuckPermsAccess.kt index 6df1636b0..8c41efac6 100644 --- a/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/luckperms/LuckPermsAccess.kt +++ b/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/luckperms/LuckPermsAccess.kt @@ -42,6 +42,7 @@ inline fun User.getMeta(key: String, default: T): T { } -fun Audience.getLuckPermsUser() = this.uuidOrNull()?.let { LuckPermsAccess.getUser(it) } -fun Audience.getLuckPermsUserOrNull() = this.uuidOrNull()?.let { LuckPermsAccess.getUser(it) } - ?: error("Audience does not have a valid UUID or LuckPerms user could not be found.") \ No newline at end of file +fun Audience.getLuckPermsUser(): User = this.getLuckPermsUserOrNull() + ?: error("Audience does not have a valid UUID or LuckPerms user could not be found.") + +fun Audience.getLuckPermsUserOrNull(): User? = this.uuidOrNull()?.let { LuckPermsAccess.getUser(it) } \ No newline at end of file From e353f92eefa1ca6c4953493bb4d9ad1e2fbd3e5e Mon Sep 17 00:00:00 2001 From: twisti <76837088+twisti-dev@users.noreply.github.com> Date: Sat, 18 Apr 2026 20:02:04 +0200 Subject: [PATCH 32/34] =?UTF-8?q?=E2=9C=A8=20feat(nms):=20call=20provider.?= =?UTF-8?q?initialize=20before=20creating=20packet=20listeners?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - move provider.initialize call before createPacketListeners to ensure proper initialization order --- .../dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt index d2acb1200..531a2b57b 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt @@ -28,6 +28,8 @@ object PacketApiLoader { // Register version-specific packet listeners from NmsProvider val provider = NmsProvider.current + provider.initialize() + versionPacketListeners = provider.createPacketListeners() for (listener in versionPacketListeners) { SurfPaperPacketListenerApi.registerListeners(listener) @@ -35,8 +37,6 @@ object PacketApiLoader { AbstractChannelInjector.instance.register() PluginDisablePacketLoreListener.register() - - provider.initialize() } @OptIn(NmsUseWithCaution::class) From 5782ae9120cc47bf1fe4703b2626725111494d8d Mon Sep 17 00:00:00 2001 From: twisti <76837088+twisti-dev@users.noreply.github.com> Date: Sat, 18 Apr 2026 20:04:25 +0200 Subject: [PATCH 33/34] =?UTF-8?q?=E2=9C=A8=20feat(nms):=20move=20provider.?= =?UTF-8?q?shutdown=20to=20after=20listener=20unregistration=20in=20onDisa?= =?UTF-8?q?ble?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - call provider.shutdown after unregistering listeners and terminating packet events in onDisable - ensures shutdown occurs after all listeners and injectors are properly unregistered --- .../dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt index 531a2b57b..85569bfde 100644 --- a/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt +++ b/surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/packet/PacketApiLoader.kt @@ -42,7 +42,6 @@ object PacketApiLoader { @OptIn(NmsUseWithCaution::class) fun onDisable() { val provider = NmsProvider.current - provider.shutdown() packetEvents.terminate() for (listener in versionPacketListeners) { @@ -52,6 +51,7 @@ object PacketApiLoader { PluginDisablePacketLoreListener.unregister() AbstractChannelInjector.instance.unregister() + provider.shutdown() } private fun setupPacketEvents() { From 584ad65e8cc436bf3f15329e21c72680c9c0be04 Mon Sep 17 00:00:00 2001 From: twisti <76837088+twisti-dev@users.noreply.github.com> Date: Sat, 18 Apr 2026 20:06:52 +0200 Subject: [PATCH 34/34] =?UTF-8?q?=E2=9C=A8=20feat(luckperms):=20update=20l?= =?UTF-8?q?uckperms=20property=20to=20use=20getter=20with=20direct=20provi?= =?UTF-8?q?der=20access?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - replace lazy delegate with property getter that calls LuckPermsProvider.get() directly - ensures latest instance is always returned when accessing luckperms property --- .../dev/slne/surf/api/core/luckperms/LuckPermsAccess.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/luckperms/LuckPermsAccess.kt b/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/luckperms/LuckPermsAccess.kt index 8c41efac6..260ad924e 100644 --- a/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/luckperms/LuckPermsAccess.kt +++ b/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/luckperms/LuckPermsAccess.kt @@ -9,9 +9,7 @@ import net.luckperms.api.node.NodeType import java.util.* object LuckPermsAccess { - val luckperms by lazy { - LuckPermsProvider.get() - } + val luckperms get() = LuckPermsProvider.get() fun getUser(uuid: UUID) = luckperms.userManager.getUser(uuid) suspend fun loadUser(uuid: UUID): User = luckperms.userManager.loadUser(uuid).await()