diff --git a/gradle.properties b/gradle.properties index 602d7094c..5543a359b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,6 +7,6 @@ org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled javaVersion=25 mcVersion=1.21.11 group=dev.slne.surf -version=1.21.11-2.63.0 +version=1.21.11-2.63.1 relocationPrefix=dev.slne.surf.surfapi.libs snapshot=false diff --git a/surf-api-bukkit/surf-api-bukkit-server/src/main/kotlin/dev/slne/surf/surfapi/bukkit/server/packet/lore/PacketLoreListener.kt b/surf-api-bukkit/surf-api-bukkit-server/src/main/kotlin/dev/slne/surf/surfapi/bukkit/server/packet/lore/PacketLoreListener.kt index 2cb3b6787..ec67a149d 100644 --- a/surf-api-bukkit/surf-api-bukkit-server/src/main/kotlin/dev/slne/surf/surfapi/bukkit/server/packet/lore/PacketLoreListener.kt +++ b/surf-api-bukkit/surf-api-bukkit-server/src/main/kotlin/dev/slne/surf/surfapi/bukkit/server/packet/lore/PacketLoreListener.kt @@ -5,18 +5,19 @@ import dev.slne.surf.surfapi.bukkit.api.packet.listener.listener.PacketListener import dev.slne.surf.surfapi.bukkit.api.packet.listener.listener.annotation.ClientboundListener import dev.slne.surf.surfapi.bukkit.api.packet.listener.listener.annotation.ServerboundListener import dev.slne.surf.surfapi.bukkit.api.packet.lore.SurfBukkitPacketLoreHandler +import dev.slne.surf.surfapi.bukkit.api.util.key import dev.slne.surf.surfapi.bukkit.server.nms.toBukkit import dev.slne.surf.surfapi.bukkit.server.nms.toNms -import dev.slne.surf.surfapi.core.api.util.* -import it.unimi.dsi.fastutil.objects.ObjectSet +import dev.slne.surf.surfapi.core.api.util.mutableObjectListOf import net.kyori.adventure.text.format.TextDecoration import net.minecraft.core.component.DataComponents -import net.minecraft.network.chat.Component import net.minecraft.network.protocol.game.* 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 java.util.concurrent.ConcurrentHashMap /** * PacketLoreListener is a class that implements PacketListenerAbstract and is responsible for @@ -24,14 +25,10 @@ import org.bukkit.plugin.Plugin */ @OptIn(NmsUseWithCaution::class) object PacketLoreListener : PacketListener { - private val loreHandlers = - mutableObject2ObjectMapOf().synchronize() - private val loreHandlersGlobal = - mutableObject2ObjectMapOf>().synchronize() + private val loreHandlers = ConcurrentHashMap() + private val loreHandlersGlobal = ConcurrentHashMap>() - - private const val LORE_PREFIX_STRING = "§q" - private val lorePrefix = Component.literal(LORE_PREFIX_STRING) + private val ORIGINAL_LORE_KEY = key("original_lore") @ServerboundListener fun onPacketReceive(event: ServerboundSetCreativeModeSlotPacket) { @@ -39,25 +36,36 @@ object PacketLoreListener : PacketListener { } @ClientboundListener - fun onWindowItem(event: ClientboundContainerSetContentPacket) { - for (item in event.items) { - makeUpdatedItemStack(item) - } + fun onWindowItem(event: ClientboundContainerSetContentPacket): ClientboundContainerSetContentPacket { + return ClientboundContainerSetContentPacket( + event.containerId(), + event.stateId(), + event.items.map { makeUpdatedItemStack(it.copy()) }, + makeUpdatedItemStack(event.carriedItem().copy()) + ) } @ClientboundListener - fun onContainerData(event: ClientboundContainerSetSlotPacket) { - makeUpdatedItemStack(event.item) + fun onContainerData(event: ClientboundContainerSetSlotPacket): ClientboundContainerSetSlotPacket { + return ClientboundContainerSetSlotPacket( + event.containerId, + event.stateId, + event.slot, + makeUpdatedItemStack(event.item.copy()) + ) } @ClientboundListener - fun onSetPlayerInventoryPacket(event: ClientboundSetPlayerInventoryPacket) { - makeUpdatedItemStack(event.contents) + fun onSetPlayerInventoryPacket(event: ClientboundSetPlayerInventoryPacket): ClientboundSetPlayerInventoryPacket { + return ClientboundSetPlayerInventoryPacket( + event.slot(), + makeUpdatedItemStack(event.contents.copy()) + ) } @ClientboundListener - fun onSetCursorItemPacket(event: ClientboundSetCursorItemPacket) { - makeUpdatedItemStack(event.contents) + fun onSetCursorItemPacket(event: ClientboundSetCursorItemPacket): ClientboundSetCursorItemPacket { + return ClientboundSetCursorItemPacket(makeUpdatedItemStack(event.contents.copy())) } private fun makeUpdatedItemStack( @@ -68,54 +76,57 @@ object PacketLoreListener : PacketListener { val bukkitStack = item.asBukkitMirror() val pdc = bukkitStack.persistentDataContainer - val nmsLore = item.get(DataComponents.LORE) - val lines = nmsLore?.lines - val lore = - lines?.mapTo(mutableObjectListOf(lines.size)) { it.toBukkit() } ?: emptyObjectList() + val nmsLore = item.getOrDefault(DataComponents.LORE, ItemLore.EMPTY) + val lines = nmsLore.lines + val mutableLore = lines.mapTo(mutableObjectListOf(lines.size)) { it.toBukkit() } loreHandlers.forEach { (identifier, handler) -> if (pdc.has(identifier)) { - handler.handleLore(lore, pdc, bukkitStack) + handler.handleLore(mutableLore, pdc, bukkitStack) } } loreHandlersGlobal.forEach { (plugin, handlers) -> if (plugin.isEnabled) { - handlers.forEach { it.handleLore(lore, pdc, bukkitStack) } + handlers.forEach { it.handleLore(mutableLore, pdc, bukkitStack) } } } val updatedNmsLore = ItemLore( - lore.asSequence() + mutableLore.asSequence() .map { it.decorationIfAbsent(TextDecoration.ITALIC, TextDecoration.State.FALSE) } .map { it.toNms() } - .map { lorePrefix.copy().append(it) } .toList() ) item.set(DataComponents.LORE, updatedNmsLore) + CustomData.update(DataComponents.CUSTOM_DATA, item) { tag -> + tag.store(ORIGINAL_LORE_KEY.asString(), ItemLore.CODEC, nmsLore) + } + return item } private fun makeCleanItemStack( - stack: ItemStack?, - ): ItemStack? { - if (stack == null) return null - - val updatedLore = stack.components.get(DataComponents.LORE) - ?.lines?.filter { !it.string.startsWith(LORE_PREFIX_STRING) } - ?: return stack + stack: ItemStack, + ): ItemStack { + CustomData.update(DataComponents.CUSTOM_DATA, stack) { tag -> + val originalLore = tag.read(ORIGINAL_LORE_KEY.asString(), ItemLore.CODEC) + originalLore.ifPresent { lore -> + stack.set(DataComponents.LORE, lore) + tag.remove(ORIGINAL_LORE_KEY.asString()) + } + } - stack.set(DataComponents.LORE, ItemLore(updatedLore)) return stack } fun register(identifier: NamespacedKey, listener: SurfBukkitPacketLoreHandler) { - loreHandlers.put(identifier, listener) + loreHandlers[identifier] = listener } fun register(plugin: Plugin, listener: SurfBukkitPacketLoreHandler) { - loreHandlersGlobal.computeIfAbsent(plugin) { mutableObjectSetOf() }.add(listener) + loreHandlersGlobal.computeIfAbsent(plugin) { ConcurrentHashMap.newKeySet() }.add(listener) } fun unregister(identifier: NamespacedKey) {