Skip to content

Commit 3698b28

Browse files
committed
feat: enhance packet handling with new inventory and cursor item listeners
1 parent 16a0c70 commit 3698b28

File tree

4 files changed

+56
-16
lines changed

4 files changed

+56
-16
lines changed

.idea/kotlinc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package dev.slne.surf.surfapi.bukkit.server.packet.listener
22

3+
import com.github.benmanes.caffeine.cache.Caffeine
4+
import com.sksamuel.aedile.core.expireAfterAccess
35
import dev.slne.surf.surfapi.bukkit.api.nms.NmsUseWithCaution
46
import dev.slne.surf.surfapi.bukkit.api.nms.nmsBridge
57
import dev.slne.surf.surfapi.bukkit.server.impl.nms.SurfBukkitNmsBridgeImpl
@@ -13,26 +15,27 @@ import dev.slne.surf.surfapi.core.api.reflection.SurfProxy
1315
import dev.slne.surf.surfapi.core.api.reflection.createProxy
1416
import dev.slne.surf.surfapi.core.api.reflection.surfReflection
1517
import dev.slne.surf.surfapi.core.api.util.logger
16-
import dev.slne.surf.surfapi.core.api.util.mutableObject2ObjectMapOf
1718
import dev.slne.surf.surfapi.core.api.util.mutableObjectSetOf
1819
import dev.slne.surf.surfapi.core.api.util.synchronize
1920
import io.netty.channel.Channel
2021
import io.netty.channel.ChannelDuplexHandler
2122
import io.netty.channel.ChannelHandlerContext
2223
import io.netty.channel.ChannelPromise
24+
import io.papermc.paper.connection.PaperPlayerLoginConnection
2325
import io.papermc.paper.connection.ReadablePlayerCookieConnectionImpl
2426
import io.papermc.paper.event.connection.PlayerConnectionValidateLoginEvent
2527
import io.papermc.paper.network.ChannelInitializeListenerHolder
2628
import net.kyori.adventure.key.Key
2729
import net.minecraft.network.Connection
2830
import net.minecraft.network.HandlerNames
2931
import net.minecraft.network.protocol.Packet
30-
import net.minecraft.server.level.ServerPlayer
32+
import net.minecraft.network.protocol.login.ClientboundLoginFinishedPacket
3133
import org.bukkit.event.EventHandler
3234
import org.bukkit.event.EventPriority
3335
import org.bukkit.event.Listener
3436
import org.bukkit.event.player.PlayerJoinEvent
3537
import java.util.*
38+
import kotlin.time.Duration.Companion.minutes
3639
import dev.slne.surf.surfapi.bukkit.api.event.register as registerListener
3740
import dev.slne.surf.surfapi.bukkit.api.event.unregister as unregisterListener
3841

@@ -42,7 +45,11 @@ object PlayerChannelInjector : Listener {
4245
private val CHANNEL_KEY = Key.key("surf-api", "packet-listener")
4346
private const val CHANNEL_NAME = "surf_api_packet_listener"
4447

45-
private val playerInjectorCache = mutableObject2ObjectMapOf<UUID, ServerPlayer>().synchronize()
48+
private val playerInjectorCache = Caffeine.newBuilder()
49+
.weakValues()
50+
.expireAfterAccess(1.minutes)
51+
.build<UUID, Connection>()
52+
4653
private val injectedChannels = mutableObjectSetOf<Channel>().synchronize()
4754

4855
fun register() {
@@ -76,21 +83,29 @@ object PlayerChannelInjector : Listener {
7683
@EventHandler
7784
fun onPlayerLogin(event: PlayerConnectionValidateLoginEvent) {
7885
val paperConnection = event.connection
79-
if (paperConnection is ReadablePlayerCookieConnectionImpl) {
86+
if (paperConnection is PaperPlayerLoginConnection) {
87+
val profile =
88+
paperConnection.authenticatedProfile ?: error("Authenticated profile is null")
8089
val connection =
8190
ReadablePlayerCookieConnectionImplProxy.instance.getConnection(paperConnection)
82-
injectChannel(connection.channel).connection = connection
91+
playerInjectorCache.put(
92+
profile.id ?: error("PlayerProfile does not provide a uuid"),
93+
connection
94+
)
8395
}
8496
}
8597

8698
@EventHandler(priority = EventPriority.LOWEST)
8799
fun onPlayerJoin(event: PlayerJoinEvent) {
88100
val player = event.player.toNms()
89-
90101
val connection = player.connection.connection
91102
val channelHandler = connection.channel.pipeline().get(CHANNEL_NAME)
92103

93104
if (channelHandler != null) {
105+
if (channelHandler is PacketHandler) {
106+
channelHandler.connection = connection
107+
playerInjectorCache.invalidate(player.uuid)
108+
}
94109
return
95110
}
96111

@@ -119,8 +134,17 @@ object PlayerChannelInjector : Listener {
119134
return
120135
}
121136

122-
val connection = this@PacketHandler.connection
123-
if (connection == null) {
137+
if (connection == null && msg is ClientboundLoginFinishedPacket) {
138+
val uuid = msg.gameProfile().id
139+
val cachedConnection = playerInjectorCache.getIfPresent(uuid)
140+
if (cachedConnection != null) {
141+
connection = cachedConnection
142+
}
143+
}
144+
145+
val connection = connection
146+
val player = connection?.player
147+
if (connection == null || player == null) {
124148
super.write(ctx, msg, promise)
125149
return
126150
}
@@ -161,8 +185,9 @@ object PlayerChannelInjector : Listener {
161185
return
162186
}
163187

164-
val connection = this@PacketHandler.connection
165-
if (connection == null) {
188+
val connection = connection
189+
val player = connection?.player
190+
if (connection == null || player == null) {
166191
super.channelRead(ctx, msg)
167192
return
168193
}

surf-api-bukkit/surf-api-bukkit-server/src/main/kotlin/dev/slne/surf/surfapi/bukkit/server/packet/lore/PacketLoreListener.kt

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ import it.unimi.dsi.fastutil.objects.ObjectSet
1212
import net.kyori.adventure.text.format.TextDecoration
1313
import net.minecraft.core.component.DataComponents
1414
import net.minecraft.network.chat.Component
15-
import net.minecraft.network.protocol.game.ClientboundContainerSetContentPacket
16-
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket
17-
import net.minecraft.network.protocol.game.ServerboundSetCreativeModeSlotPacket
15+
import net.minecraft.network.protocol.game.*
1816
import net.minecraft.world.item.ItemStack
1917
import net.minecraft.world.item.component.ItemLore
2018
import org.bukkit.NamespacedKey
@@ -52,8 +50,18 @@ object PacketLoreListener : PacketListener {
5250
makeUpdatedItemStack(event.item)
5351
}
5452

53+
@ClientboundListener
54+
fun onSetPlayerInventoryPacket(event: ClientboundSetPlayerInventoryPacket) {
55+
makeUpdatedItemStack(event.contents)
56+
}
57+
58+
@ClientboundListener
59+
fun onSetCursorItemPacket(event: ClientboundSetCursorItemPacket) {
60+
makeUpdatedItemStack(event.contents)
61+
}
62+
5563
private fun makeUpdatedItemStack(
56-
item: ItemStack
64+
item: ItemStack,
5765
): ItemStack {
5866
if (item.isEmpty) return item
5967
if (loreHandlers.isEmpty() && loreHandlersGlobal.isEmpty()) return item
@@ -90,7 +98,7 @@ object PacketLoreListener : PacketListener {
9098
}
9199

92100
private fun makeCleanItemStack(
93-
stack: ItemStack?
101+
stack: ItemStack?,
94102
): ItemStack? {
95103
if (stack == null) return null
96104

0 commit comments

Comments
 (0)