Skip to content

Commit 20e62b2

Browse files
authored
Implement suspend command requirements and optimize packet handling (#358)
2 parents b9c71b0 + f81d61c commit 20e62b2

15 files changed

Lines changed: 442 additions & 2 deletions

File tree

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled
77
javaVersion=25
88
mcVersion=26.1.2
99
group=dev.slne.surf.api
10-
version=3.15.0
10+
version=3.16.0
1111
relocationPrefix=dev.slne.surf.api.libs
1212
snapshot=false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package dev.slne.surf.api.paper.nms.common
2+
3+
import dev.slne.surf.api.paper.nms.NmsUseWithCaution
4+
import dev.slne.surf.api.paper.packet.listener.listener.PacketListener
5+
import java.util.*
6+
import java.util.concurrent.ConcurrentHashMap
7+
8+
@OptIn(NmsUseWithCaution::class)
9+
abstract class CommandSendPacketBlockerListener(protected val blockedPlayers: Set<UUID>) : PacketListener {
10+
protected val receivedFirstCommandPacket: MutableSet<UUID> = ConcurrentHashMap.newKeySet()
11+
12+
fun removeReceivedFirstCommandPacket(uuid: UUID) {
13+
receivedFirstCommandPacket.remove(uuid)
14+
}
15+
}

surf-api-paper/surf-api-paper-nms/surf-api-paper-nms-common/src/main/kotlin/dev/slne/surf/api/paper/nms/common/NmsProvider.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import dev.slne.surf.api.shared.internal.nms.NmsVersion
1818
import org.bukkit.plugin.java.JavaPlugin
1919
import java.io.File
2020
import java.net.URI
21+
import java.util.*
2122
import java.util.jar.JarFile
2223

2324
/**
@@ -84,6 +85,8 @@ interface NmsProvider {
8485
fun createChannelInjector(): AbstractChannelInjector<*>
8586
fun createPacketListenerApi(): InternalPacketListenerApiBridge
8687

88+
fun createCommandSendPacketBlockerListener(blockedPlayers: Set<UUID>): CommandSendPacketBlockerListener
89+
8790
/**
8891
* Creates version-specific packet listeners (e.g. lore handler, glowing handler).
8992
*

surf-api-paper/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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import dev.slne.surf.api.paper.server.nms.v1_21_11.bridges.packets.player.V1_21_
2222
import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.V1_21_11GlowingLifecycleHandler
2323
import dev.slne.surf.api.paper.server.nms.v1_21_11.glow.V1_21_11SurfGlowingApiImpl
2424
import dev.slne.surf.api.paper.server.nms.v1_21_11.packet.listener.V1_21_11ChannelInjector
25+
import dev.slne.surf.api.paper.server.nms.v1_21_11.packet.listener.V1_21_11CommandSendPacketBlockerListenerImpl
2526
import dev.slne.surf.api.paper.server.nms.v1_21_11.packet.listener.V1_21_11GlowingPacketListener
2627
import dev.slne.surf.api.paper.server.nms.v1_21_11.packet.lore.V1_21_11PacketLoreListener
2728
import dev.slne.surf.api.paper.server.nms.v1_21_11.packet.lore.V1_21_11PacketLoreRegistry
@@ -30,6 +31,7 @@ import dev.slne.surf.api.paper.server.nms.v1_21_11.region.V1_21_11TickThreadGuar
3031
import dev.slne.surf.api.shared.internal.nms.NmsProviderMarker
3132
import dev.slne.surf.api.shared.internal.nms.NmsVersion
3233
import org.bukkit.plugin.java.JavaPlugin
34+
import java.util.*
3335

3436
@Suppress("ClassName")
3537
@OptIn(NmsUseWithCaution::class)
@@ -89,6 +91,10 @@ class V1_21_11NmsProvider(override val plugin: JavaPlugin) : NmsProvider {
8991
override fun createChannelInjector(): AbstractChannelInjector<*> = V1_21_11ChannelInjector
9092
override fun createPacketListenerApi(): InternalPacketListenerApiBridge = V1_21_11PacketListenerApiImpl()
9193

94+
override fun createCommandSendPacketBlockerListener(blockedPlayers: Set<UUID>): CommandSendPacketBlockerListener {
95+
return V1_21_11CommandSendPacketBlockerListenerImpl(blockedPlayers)
96+
}
97+
9298
override fun createPacketListeners(): List<PacketListener> = listOf(
9399
V1_21_11PacketLoreListener,
94100
V1_21_11GlowingPacketListener,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package dev.slne.surf.api.paper.server.nms.v1_21_11.packet.listener
2+
3+
import com.mojang.brigadier.CommandDispatcher
4+
import com.mojang.brigadier.builder.LiteralArgumentBuilder
5+
import com.mojang.brigadier.tree.ArgumentCommandNode
6+
import com.mojang.brigadier.tree.CommandNode
7+
import dev.slne.surf.api.paper.nms.NmsUseWithCaution
8+
import dev.slne.surf.api.paper.nms.common.CommandSendPacketBlockerListener
9+
import dev.slne.surf.api.paper.packet.listener.listener.annotation.ClientboundListener
10+
import net.minecraft.commands.CommandSourceStack
11+
import net.minecraft.network.protocol.game.ClientboundCommandsPacket
12+
import net.minecraft.resources.Identifier
13+
import net.minecraft.server.level.ServerPlayer
14+
import java.util.*
15+
16+
@OptIn(NmsUseWithCaution::class)
17+
@Suppress("ClassName")
18+
class V1_21_11CommandSendPacketBlockerListenerImpl(blockedPlayers: Set<UUID>) :
19+
CommandSendPacketBlockerListener(blockedPlayers) {
20+
21+
private val loadingCommandsDispatcher = CommandDispatcher<CommandSourceStack>()
22+
private val commandNodeInspector = object : ClientboundCommandsPacket.NodeInspector<CommandSourceStack> {
23+
override fun suggestionId(p0: ArgumentCommandNode<CommandSourceStack, *>): Identifier? {
24+
return null
25+
}
26+
27+
override fun isExecutable(p0: CommandNode<CommandSourceStack>): Boolean {
28+
return false
29+
}
30+
31+
override fun isRestricted(p0: CommandNode<CommandSourceStack>): Boolean {
32+
return false
33+
}
34+
}
35+
36+
init {
37+
loadingCommandsDispatcher.register(LiteralArgumentBuilder.literal("commands-are-loading"))
38+
}
39+
40+
@ClientboundListener
41+
fun onClientboundCommandsPacket(
42+
packet: ClientboundCommandsPacket,
43+
player: ServerPlayer
44+
): ClientboundCommandsPacket? {
45+
if (blockedPlayers.contains(player.uuid)) {
46+
return if (receivedFirstCommandPacket.add(player.uuid)) {
47+
ClientboundCommandsPacket(loadingCommandsDispatcher.root, commandNodeInspector)
48+
} else {
49+
null
50+
}
51+
}
52+
53+
return packet
54+
}
55+
}

surf-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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import dev.slne.surf.api.paper.server.nms.v26_1.bridges.packets.player.V26_1Surf
2222
import dev.slne.surf.api.paper.server.nms.v26_1.glow.V26_1GlowingLifecycleHandler
2323
import dev.slne.surf.api.paper.server.nms.v26_1.glow.V26_1SurfGlowingApiImpl
2424
import dev.slne.surf.api.paper.server.nms.v26_1.packet.listener.V26_1ChannelInjector
25+
import dev.slne.surf.api.paper.server.nms.v26_1.packet.listener.V26_1CommandSendPacketBlockerListenerImpl
2526
import dev.slne.surf.api.paper.server.nms.v26_1.packet.listener.V26_1GlowingPacketListener
2627
import dev.slne.surf.api.paper.server.nms.v26_1.packet.lore.V26_1PacketLoreListener
2728
import dev.slne.surf.api.paper.server.nms.v26_1.packet.lore.V26_1PacketLoreRegistry
@@ -30,6 +31,7 @@ import dev.slne.surf.api.paper.server.nms.v26_1.region.V26_1TickThreadGuard
3031
import dev.slne.surf.api.shared.internal.nms.NmsProviderMarker
3132
import dev.slne.surf.api.shared.internal.nms.NmsVersion
3233
import org.bukkit.plugin.java.JavaPlugin
34+
import java.util.*
3335

3436
@Suppress("ClassName")
3537
@OptIn(NmsUseWithCaution::class)
@@ -68,6 +70,10 @@ class V26_1NmsProvider(override val plugin: JavaPlugin) : NmsProvider {
6870
override fun createChannelInjector(): AbstractChannelInjector<*> = V26_1ChannelInjector
6971
override fun createPacketListenerApi(): InternalPacketListenerApiBridge = V26_1PacketListenerApiImpl()
7072

73+
override fun createCommandSendPacketBlockerListener(blockedPlayers: Set<UUID>): CommandSendPacketBlockerListener {
74+
return V26_1CommandSendPacketBlockerListenerImpl(blockedPlayers)
75+
}
76+
7177
override fun createPacketListeners(): List<PacketListener> = listOf(
7278
V26_1PacketLoreListener,
7379
V26_1GlowingPacketListener,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package dev.slne.surf.api.paper.server.nms.v26_1.packet.listener
2+
3+
import com.mojang.brigadier.CommandDispatcher
4+
import com.mojang.brigadier.builder.LiteralArgumentBuilder
5+
import com.mojang.brigadier.tree.ArgumentCommandNode
6+
import com.mojang.brigadier.tree.CommandNode
7+
import dev.slne.surf.api.paper.nms.NmsUseWithCaution
8+
import dev.slne.surf.api.paper.nms.common.CommandSendPacketBlockerListener
9+
import dev.slne.surf.api.paper.packet.listener.listener.annotation.ClientboundListener
10+
import net.minecraft.commands.CommandSourceStack
11+
import net.minecraft.network.protocol.game.ClientboundCommandsPacket
12+
import net.minecraft.resources.Identifier
13+
import net.minecraft.server.level.ServerPlayer
14+
import java.util.*
15+
16+
17+
@Suppress("ClassName")
18+
@OptIn(NmsUseWithCaution::class)
19+
class V26_1CommandSendPacketBlockerListenerImpl(blockedPlayers: Set<UUID>) :
20+
CommandSendPacketBlockerListener(blockedPlayers) {
21+
22+
private val loadingCommandsDispatcher = CommandDispatcher<CommandSourceStack>()
23+
private val commandNodeInspector = object : ClientboundCommandsPacket.NodeInspector<CommandSourceStack> {
24+
override fun suggestionId(p0: ArgumentCommandNode<CommandSourceStack, *>): Identifier? {
25+
return null
26+
}
27+
28+
override fun isExecutable(p0: CommandNode<CommandSourceStack>): Boolean {
29+
return false
30+
}
31+
32+
override fun isRestricted(p0: CommandNode<CommandSourceStack>): Boolean {
33+
return false
34+
}
35+
}
36+
37+
init {
38+
loadingCommandsDispatcher.register(LiteralArgumentBuilder.literal("commands-are-loading"))
39+
}
40+
41+
@ClientboundListener
42+
fun onClientboundCommandsPacket(
43+
packet: ClientboundCommandsPacket,
44+
player: ServerPlayer
45+
): ClientboundCommandsPacket? {
46+
if (blockedPlayers.contains(player.uuid)) {
47+
return if (receivedFirstCommandPacket.add(player.uuid)) {
48+
ClientboundCommandsPacket(loadingCommandsDispatcher.root, commandNodeInspector)
49+
} else {
50+
null
51+
}
52+
}
53+
54+
return packet
55+
}
56+
}

surf-api-paper/surf-api-paper-plugin-test/src/main/java/dev/slne/surf/api/paper/test/command/SurfApiTestCommand.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ public SurfApiTestCommand() {
3333
new SignedMessageArgumentTest("signedmessage"),
3434
new BlockPdcContainerTest("blockpdc"),
3535
new OfflineInventoryEditTest("editOfflineInventory"),
36-
new ModernSerializerTestConfigCommand("modernSerializerTestConfig")
36+
new ModernSerializerTestConfigCommand("modernSerializerTestConfig"),
37+
new SuspendRequirementTestCommand("suspendRequirement")
3738
);
3839
}
3940
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package dev.slne.surf.surfapi.bukkit.test.command.subcommands
2+
3+
import dev.jorel.commandapi.CommandAPICommand
4+
import dev.jorel.commandapi.kotlindsl.*
5+
import dev.slne.surf.api.paper.command.requirement.withSuspendPlayerRequirement
6+
import kotlinx.coroutines.delay
7+
import java.util.*
8+
import java.util.concurrent.ConcurrentHashMap
9+
import kotlin.time.Duration.Companion.seconds
10+
11+
class SuspendRequirementTestCommand(name: String) : CommandAPICommand(name) {
12+
private val shown = ConcurrentHashMap.newKeySet<UUID>()
13+
14+
init {
15+
subcommand("updateCommands") {
16+
playerExecutor { player, _ ->
17+
player.updateCommands()
18+
}
19+
}
20+
21+
subcommand("showCommand") {
22+
booleanArgument("show")
23+
24+
playerExecutor { player, arguments ->
25+
val show: Boolean by arguments
26+
if (show) {
27+
shown.add(player.uniqueId)
28+
} else {
29+
shown.remove(player.uniqueId)
30+
}
31+
}
32+
}
33+
34+
subcommand("conditionalCommand") {
35+
withSuspendPlayerRequirement { player ->
36+
delay(10.seconds)
37+
player.uniqueId in shown
38+
}
39+
40+
anyExecutor { sender, _ ->
41+
sender.sendMessage("This command is only available to players who have shown it")
42+
}
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)