Skip to content

Commit 431b2ab

Browse files
committed
feat: enhance serverbound packet handling with custom payload support and null safety improvements
1 parent c41d158 commit 431b2ab

File tree

10 files changed

+150
-25
lines changed

10 files changed

+150
-25
lines changed

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=21
88
mcVersion=1.21.11
99
group=dev.slne.surf
10-
version=1.21.11-2.49.1
10+
version=1.21.11-2.50.0
1111
relocationPrefix=dev.slne.surf.surfapi.libs
1212
snapshot=false

surf-api-bukkit/surf-api-bukkit-api/api/surf-api-bukkit-api.api

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5511,6 +5511,7 @@ public abstract interface class dev/slne/surf/surfapi/bukkit/api/nms/listener/Nm
55115511
}
55125512

55135513
public abstract interface class dev/slne/surf/surfapi/bukkit/api/nms/listener/NmsServerboundPacketListener : dev/slne/surf/surfapi/bukkit/api/nms/listener/NmsPacketListener {
5514+
public fun handleEarlyServerboundPacket (Ldev/slne/surf/surfapi/bukkit/api/nms/listener/packets/NmsPacket;Lorg/bukkit/entity/Player;)Ldev/slne/surf/surfapi/bukkit/api/packet/listener/listener/PacketListenerResult;
55145515
public abstract fun handleServerboundPacket (Ldev/slne/surf/surfapi/bukkit/api/nms/listener/packets/NmsPacket;Lorg/bukkit/entity/Player;)Ldev/slne/surf/surfapi/bukkit/api/packet/listener/listener/PacketListenerResult;
55155516
}
55165517

@@ -5544,6 +5545,38 @@ public abstract interface class dev/slne/surf/surfapi/bukkit/api/nms/listener/pa
55445545
public abstract fun getNewName ()Ljava/lang/String;
55455546
}
55465547

5548+
public abstract interface class dev/slne/surf/surfapi/bukkit/api/nms/listener/packets/serverbound/ServerboundCustomPayloadPacket : dev/slne/surf/surfapi/bukkit/api/nms/listener/packets/serverbound/NmsServerboundPacket {
5549+
public abstract fun getPayload ()Ldev/slne/surf/surfapi/bukkit/api/nms/listener/packets/serverbound/ServerboundCustomPayloadPacket$Payload;
5550+
public abstract fun setPayload (Ldev/slne/surf/surfapi/bukkit/api/nms/listener/packets/serverbound/ServerboundCustomPayloadPacket$Payload;)V
5551+
}
5552+
5553+
public abstract interface class dev/slne/surf/surfapi/bukkit/api/nms/listener/packets/serverbound/ServerboundCustomPayloadPacket$Payload {
5554+
}
5555+
5556+
public final class dev/slne/surf/surfapi/bukkit/api/nms/listener/packets/serverbound/ServerboundCustomPayloadPacket$Payload$Brand : dev/slne/surf/surfapi/bukkit/api/nms/listener/packets/serverbound/ServerboundCustomPayloadPacket$Payload {
5557+
public fun <init> (Ljava/lang/String;)V
5558+
public final fun component1 ()Ljava/lang/String;
5559+
public final fun copy (Ljava/lang/String;)Ldev/slne/surf/surfapi/bukkit/api/nms/listener/packets/serverbound/ServerboundCustomPayloadPacket$Payload$Brand;
5560+
public static synthetic fun copy$default (Ldev/slne/surf/surfapi/bukkit/api/nms/listener/packets/serverbound/ServerboundCustomPayloadPacket$Payload$Brand;Ljava/lang/String;ILjava/lang/Object;)Ldev/slne/surf/surfapi/bukkit/api/nms/listener/packets/serverbound/ServerboundCustomPayloadPacket$Payload$Brand;
5561+
public fun equals (Ljava/lang/Object;)Z
5562+
public final fun getBrand ()Ljava/lang/String;
5563+
public fun hashCode ()I
5564+
public fun toString ()Ljava/lang/String;
5565+
}
5566+
5567+
public final class dev/slne/surf/surfapi/bukkit/api/nms/listener/packets/serverbound/ServerboundCustomPayloadPacket$Payload$Discarded : dev/slne/surf/surfapi/bukkit/api/nms/listener/packets/serverbound/ServerboundCustomPayloadPacket$Payload {
5568+
public fun <init> (Lnet/kyori/adventure/key/Key;[B)V
5569+
public final fun component1 ()Lnet/kyori/adventure/key/Key;
5570+
public final fun component2 ()[B
5571+
public final fun copy (Lnet/kyori/adventure/key/Key;[B)Ldev/slne/surf/surfapi/bukkit/api/nms/listener/packets/serverbound/ServerboundCustomPayloadPacket$Payload$Discarded;
5572+
public static synthetic fun copy$default (Ldev/slne/surf/surfapi/bukkit/api/nms/listener/packets/serverbound/ServerboundCustomPayloadPacket$Payload$Discarded;Lnet/kyori/adventure/key/Key;[BILjava/lang/Object;)Ldev/slne/surf/surfapi/bukkit/api/nms/listener/packets/serverbound/ServerboundCustomPayloadPacket$Payload$Discarded;
5573+
public fun equals (Ljava/lang/Object;)Z
5574+
public final fun getData ()[B
5575+
public final fun getId ()Lnet/kyori/adventure/key/Key;
5576+
public fun hashCode ()I
5577+
public fun toString ()Ljava/lang/String;
5578+
}
5579+
55475580
public abstract interface class dev/slne/surf/surfapi/bukkit/api/nms/listener/packets/serverbound/SignUpdatePacket : dev/slne/surf/surfapi/bukkit/api/nms/listener/packets/serverbound/NmsServerboundPacket {
55485581
public abstract fun getLine (I)Ljava/lang/String;
55495582
public abstract fun getLines ()[Ljava/lang/String;

surf-api-bukkit/surf-api-bukkit-api/src/main/java/dev/slne/surf/surfapi/bukkit/api/nms/listener/NmsServerboundPacketListener.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,21 @@
55
import dev.slne.surf.surfapi.bukkit.api.packet.listener.listener.PacketListenerResult;
66
import org.bukkit.entity.Player;
77
import org.jetbrains.annotations.ApiStatus.OverrideOnly;
8+
import org.jspecify.annotations.Nullable;
89

910
@NmsUseWithCaution
1011
public interface NmsServerboundPacketListener<Packet extends NmsPacket> extends
11-
NmsPacketListener<Packet> {
12+
NmsPacketListener<Packet> {
1213

13-
@OverrideOnly
14-
PacketListenerResult handleServerboundPacket(Packet packet, Player player);
14+
@OverrideOnly
15+
PacketListenerResult handleServerboundPacket(Packet packet, Player player);
16+
17+
@OverrideOnly
18+
default PacketListenerResult handleEarlyServerboundPacket(Packet packet, @Nullable Player player) {
19+
if (player != null) {
20+
return handleServerboundPacket(packet, player);
21+
} else {
22+
return PacketListenerResult.CONTINUE;
23+
}
24+
}
1525
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package dev.slne.surf.surfapi.bukkit.api.nms.listener.packets.serverbound
2+
3+
import dev.slne.surf.surfapi.bukkit.api.nms.NmsUseWithCaution
4+
import net.kyori.adventure.key.Key
5+
6+
@NmsUseWithCaution
7+
interface ServerboundCustomPayloadPacket: NmsServerboundPacket {
8+
9+
var payload: Payload
10+
11+
sealed interface Payload {
12+
data class Brand(val brand: String) : Payload
13+
data class Discarded(val id: Key, val data: ByteArray) : Payload {
14+
override fun equals(other: Any?): Boolean {
15+
if (this === other) return true
16+
if (javaClass != other?.javaClass) return false
17+
18+
other as Discarded
19+
20+
if (id != other.id) return false
21+
if (!data.contentEquals(other.data)) return false
22+
23+
return true
24+
}
25+
26+
override fun hashCode(): Int {
27+
var result = id.hashCode()
28+
result = 31 * result + data.contentHashCode()
29+
return result
30+
}
31+
}
32+
}
33+
}

surf-api-bukkit/surf-api-bukkit-server/src/main/kotlin/dev/slne/surf/surfapi/bukkit/server/impl/nms/SurfBukkitNmsBridgeImpl.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,15 @@ class SurfBukkitNmsBridgeImpl : SurfBukkitNmsBridge {
7676
@Suppress("UNCHECKED_CAST")
7777
fun <Packet : NmsServerboundPacket> handleServerboundPacket(
7878
packet: Packet,
79-
player: Player,
79+
player: Player?,
8080
): Packet? {
8181
val clazz = packet.packetClass
8282
val listener = serverboundPacketListeners[clazz] ?: return packet
8383

8484
var cancel = false
8585
for (listener in listener) {
8686
listener as NmsServerboundPacketListener<Packet>
87-
val result = listener.handleServerboundPacket(packet, player)
87+
val result = listener.handleEarlyServerboundPacket(packet, player)
8888
if (result == PacketListenerResult.CANCEL) {
8989
cancel = true
9090
}

surf-api-bukkit/surf-api-bukkit-server/src/main/kotlin/dev/slne/surf/surfapi/bukkit/server/impl/nms/listener/packets/PacketRegistry.kt

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,39 +7,44 @@ import dev.slne.surf.surfapi.bukkit.server.impl.nms.listener.packets.clientbound
77
import dev.slne.surf.surfapi.bukkit.server.impl.nms.listener.packets.clientbound.ClientboundSystemChatPacketImpl
88
import dev.slne.surf.surfapi.bukkit.server.impl.nms.listener.packets.serverbound.CommandSuggestionPacketImpl
99
import dev.slne.surf.surfapi.bukkit.server.impl.nms.listener.packets.serverbound.RenameItemPacketImpl
10+
import dev.slne.surf.surfapi.bukkit.server.impl.nms.listener.packets.serverbound.ServerboundCustomPayloadPacketImpl
1011
import dev.slne.surf.surfapi.bukkit.server.impl.nms.listener.packets.serverbound.SignUpdatePacketImpl
1112
import dev.slne.surf.surfapi.core.api.util.mutableObject2ObjectMapOf
1213
import net.minecraft.network.protocol.Packet
1314
import net.minecraft.network.protocol.common.ClientCommonPacketListener
1415
import net.minecraft.network.protocol.common.ClientboundDisconnectPacket
15-
import net.minecraft.network.protocol.game.*
16+
import net.minecraft.network.protocol.common.ServerCommonPacketListener
17+
import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket
18+
import net.minecraft.network.protocol.game.ClientboundSystemChatPacket
19+
import net.minecraft.network.protocol.game.ServerboundCommandSuggestionPacket
20+
import net.minecraft.network.protocol.game.ServerboundRenameItemPacket
21+
import net.minecraft.network.protocol.game.ServerboundSignUpdatePacket
1622
import kotlin.reflect.KClass
1723

1824
@OptIn(NmsUseWithCaution::class)
1925
object PacketRegistry {
20-
private val SERVERBOUND_PACKETS =
21-
mutableObject2ObjectMapOf<Class<out Packet<*>>, ServerboundPacketFactory<*, *>>()
22-
private val CLIENTBOUND_PACKETS =
23-
mutableObject2ObjectMapOf<Class<out Packet<*>>, ClientboundPacketFactory<*, *>>()
26+
private val SERVERBOUND_PACKETS = mutableObject2ObjectMapOf<Class<out Packet<*>>, ServerboundPacketFactory<*, *>>()
27+
private val CLIENTBOUND_PACKETS = mutableObject2ObjectMapOf<Class<out Packet<*>>, ClientboundPacketFactory<*, *>>()
2428

2529
init {
2630
// @formatter:off
2731
// Serverbound packets
2832
registerServerboundPacket(ServerboundSignUpdatePacket::class) { SignUpdatePacketImpl(it) }
2933
registerServerboundPacket(ServerboundRenameItemPacket::class) { RenameItemPacketImpl(it) }
3034
registerServerboundPacket(ServerboundCommandSuggestionPacket::class) { CommandSuggestionPacketImpl(it) }
35+
registerServerboundPacket(ServerboundCustomPayloadPacket::class) { ServerboundCustomPayloadPacketImpl(it) }
3136

3237
// Clientbound packets
3338
registerClientboundPacket(ClientboundDisconnectPacket::class) { ClientboundDisconnectPacketImpl(it) }
3439
registerClientboundPacket(ClientboundSystemChatPacket::class) { ClientboundSystemChatPacketImpl(it) }
3540
// @formatter:on
3641
}
3742

38-
private fun <Nms : Packet<ServerGamePacketListener>, Api : NmsServerboundPacket> registerServerboundPacket(
43+
private fun <Nms : Packet<out ServerCommonPacketListener>, Api : NmsServerboundPacket> registerServerboundPacket(
3944
nms: KClass<Nms>,
4045
factory: ServerboundPacketFactory<Nms, Api>,
4146
) {
42-
SERVERBOUND_PACKETS.put(nms.java, factory)
47+
SERVERBOUND_PACKETS[nms.java] = factory
4348
}
4449

4550
@Suppress("UNCHECKED_CAST")
@@ -52,7 +57,7 @@ object PacketRegistry {
5257
nms: KClass<Nms>,
5358
factory: ClientboundPacketFactory<Nms, Api>,
5459
) {
55-
CLIENTBOUND_PACKETS.put(nms.java, factory)
60+
CLIENTBOUND_PACKETS[nms.java] = factory
5661
}
5762

5863
@Suppress("UNCHECKED_CAST")

surf-api-bukkit/surf-api-bukkit-server/src/main/kotlin/dev/slne/surf/surfapi/bukkit/server/impl/nms/listener/packets/serverbound/NmsServerboundPacketImpl.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ package dev.slne.surf.surfapi.bukkit.server.impl.nms.listener.packets.serverboun
33
import dev.slne.surf.surfapi.bukkit.api.nms.NmsUseWithCaution
44
import dev.slne.surf.surfapi.bukkit.server.impl.nms.listener.packets.NmsPacketImpl
55
import net.minecraft.network.protocol.Packet
6-
import net.minecraft.network.protocol.game.ServerGamePacketListener
6+
import net.minecraft.network.protocol.common.ServerCommonPacketListener
77

88
@NmsUseWithCaution
9-
abstract class NmsServerboundPacketImpl<Nms : Packet<ServerGamePacketListener>>(nmsPacket: Nms) :
10-
NmsPacketImpl<Nms, ServerGamePacketListener>(nmsPacket)
9+
abstract class NmsServerboundPacketImpl<Nms : Packet<out ServerCommonPacketListener>>(nmsPacket: Nms) :
10+
NmsPacketImpl<Nms, ServerCommonPacketListener>(nmsPacket)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package dev.slne.surf.surfapi.bukkit.server.impl.nms.listener.packets.serverbound
2+
3+
import dev.slne.surf.surfapi.bukkit.api.nms.NmsUseWithCaution
4+
import dev.slne.surf.surfapi.bukkit.api.nms.listener.packets.serverbound.ServerboundCustomPayloadPacket.Payload
5+
import io.papermc.paper.adventure.PaperAdventure
6+
import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket
7+
import net.minecraft.network.protocol.common.custom.BrandPayload
8+
import net.minecraft.network.protocol.common.custom.CustomPacketPayload
9+
import net.minecraft.network.protocol.common.custom.DiscardedPayload
10+
11+
@NmsUseWithCaution
12+
class ServerboundCustomPayloadPacketImpl(
13+
nmsPacket: ServerboundCustomPayloadPacket
14+
) : NmsServerboundPacketImpl<ServerboundCustomPayloadPacket>(nmsPacket),
15+
dev.slne.surf.surfapi.bukkit.api.nms.listener.packets.serverbound.ServerboundCustomPayloadPacket {
16+
17+
override var payload: Payload
18+
get() = toApiPayload(nmsPacket.payload);
19+
set(value) {
20+
nmsPacket = ServerboundCustomPayloadPacket(toNmsPayload(value))
21+
}
22+
23+
companion object {
24+
private fun toApiPayload(nmsPayload: CustomPacketPayload): Payload = when (nmsPayload) {
25+
is BrandPayload -> Payload.Brand(nmsPayload.brand)
26+
is DiscardedPayload -> Payload.Discarded(
27+
id = PaperAdventure.asAdventure(nmsPayload.id),
28+
data = nmsPayload.data
29+
)
30+
31+
else -> error("Unknown CustomPacketPayload type: ${nmsPayload.type()}")
32+
}
33+
34+
private fun toNmsPayload(apiPayload: Payload): CustomPacketPayload = when (apiPayload) {
35+
is Payload.Brand -> BrandPayload(apiPayload.brand)
36+
is Payload.Discarded -> DiscardedPayload(
37+
PaperAdventure.asVanilla(apiPayload.id),
38+
apiPayload.data
39+
)
40+
}
41+
}
42+
}

surf-api-bukkit/surf-api-bukkit-server/src/main/kotlin/dev/slne/surf/surfapi/bukkit/server/impl/packet/listener/SurfBukkitPacketListenerApiImpl.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class SurfBukkitPacketListenerApiImpl : SurfBukkitPacketListenerApi {
107107

108108
fun handleServerboundPacket(
109109
packet: Packet<*>,
110-
serverPlayer: ServerPlayer
110+
serverPlayer: ServerPlayer?
111111
): Packet<*>? {
112112
val methods = serverboundListenerMethods[packet.javaClass] ?: return packet
113113
var result: Packet<*>? = packet
@@ -131,12 +131,12 @@ class SurfBukkitPacketListenerApiImpl : SurfBukkitPacketListenerApi {
131131

132132
private fun callListener(
133133
listenerMethod: ListenerMethod,
134-
serverPlayer: ServerPlayer,
134+
serverPlayer: ServerPlayer?,
135135
packet: Packet<*>
136136
): Packet<*>? {
137137
if (listenerMethod.hasPlayerParameter) {
138138
val player =
139-
if (listenerMethod.hasServerPlayerParameter) serverPlayer else serverPlayer.bukkitEntity
139+
if (listenerMethod.hasServerPlayerParameter) serverPlayer else serverPlayer?.bukkitEntity
140140
val result = listenerMethod.methodHandle(listenerMethod.listener, packet, player)
141141
if (result is PacketListenerResult && result == PacketListenerResult.CANCEL) {
142142
return null
@@ -163,6 +163,6 @@ class SurfBukkitPacketListenerApiImpl : SurfBukkitPacketListenerApi {
163163
val listener: PacketListener,
164164
val methodHandle: MethodHandle,
165165
val hasPlayerParameter: Boolean,
166-
val hasServerPlayerParameter: Boolean
166+
val hasServerPlayerParameter: Boolean,
167167
)
168168
}

surf-api-bukkit/surf-api-bukkit-server/src/main/kotlin/dev/slne/surf/surfapi/bukkit/server/packet/listener/PlayerChannelInjector.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ object PlayerChannelInjector : Listener {
177177
}
178178
}
179179

180+
@Suppress("UNNECESSARY_SAFE_CALL")
180181
@OptIn(NmsUseWithCaution::class)
181182
override fun channelRead(ctx: ChannelHandlerContext?, msg: Any?) { // client -> server
182183
var msg = msg
@@ -186,17 +187,17 @@ object PlayerChannelInjector : Listener {
186187
}
187188

188189
val connection = connection
189-
val player = connection?.player
190-
if (connection == null || player == null) {
190+
if (connection == null) {
191191
super.channelRead(ctx, msg)
192192
return
193193
}
194194

195+
val player = connection?.player
195196
var cancelled = false
196197

197198
try {
198199
// first, we try to handle the packet with the nms packet listener
199-
msg = this.packetListenerApi.handleServerboundPacket(msg, connection.player)
200+
msg = this.packetListenerApi.handleServerboundPacket(msg, player)
200201

201202
if (msg == null) {
202203
// no need to handle the packet further
@@ -221,6 +222,7 @@ object PlayerChannelInjector : Listener {
221222
}
222223

223224
@OptIn(NmsUseWithCaution::class)
225+
@Suppress("UNNECESSARY_SAFE_CALL")
224226
fun handleServerboundPacketFromBridge(
225227
connection: Connection,
226228
packet: Packet<*>,
@@ -230,7 +232,7 @@ object PlayerChannelInjector : Listener {
230232
if (apiPacket != null) { // we have an api packet wrapper for this packet
231233
val resultApi = this.bridge.handleServerboundPacket(
232234
apiPacket,
233-
connection.player.bukkitEntity
235+
connection.player?.bukkitEntity
234236
)
235237

236238
if (resultApi != null) { // we may have a modified packet

0 commit comments

Comments
 (0)