From 1e01956ba943f6ef8a0f6f1162104d917aa51885 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Sat, 6 Dec 2025 03:15:57 +0800 Subject: [PATCH] =?UTF-8?q?=E9=81=BF=E5=85=8D=E5=85=B6=E4=BB=96=E5=BC=B9?= =?UTF-8?q?=E5=B0=84=E7=89=A9=E5=BA=94=E7=94=A8=E5=8F=91=E5=85=89=E5=92=8C?= =?UTF-8?q?=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/network/BukkitNetworkManager.java | 4 +- .../handler/CommonItemPacketHandler.java | 127 +++------------- .../network/handler/ItemPacketHandler.java | 141 ++++++++++++++++++ 3 files changed, 161 insertions(+), 111 deletions(-) create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/handler/ItemPacketHandler.java diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java index 113268a15..5546b0734 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java @@ -3900,7 +3900,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes this.handlers[MEntityTypes.BLOCK_DISPLAY$registryId] = simpleAddEntityHandler(BlockDisplayPacketHandler.INSTANCE); this.handlers[MEntityTypes.TEXT_DISPLAY$registryId] = simpleAddEntityHandler(TextDisplayPacketHandler.INSTANCE); this.handlers[MEntityTypes.ARMOR_STAND$registryId] = simpleAddEntityHandler(ArmorStandPacketHandler.INSTANCE); - this.handlers[MEntityTypes.ITEM$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE); + this.handlers[MEntityTypes.ITEM$registryId] = simpleAddEntityHandler(ItemPacketHandler.INSTANCE); this.handlers[MEntityTypes.ITEM_FRAME$registryId] = simpleAddEntityHandler(ItemFramePacketHandler.INSTANCE); this.handlers[MEntityTypes.GLOW_ITEM_FRAME$registryId] = simpleAddEntityHandler(ItemFramePacketHandler.INSTANCE); this.handlers[MEntityTypes.ENDERMAN$registryId] = simpleAddEntityHandler(EndermanPacketHandler.INSTANCE); @@ -3927,7 +3927,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes this.handlers[MEntityTypes.TNT$registryId] = simpleAddEntityHandler(PrimedTNTPacketHandler.INSTANCE); } if (VersionHelper.isOrAbove1_20_5()) { - this.handlers[MEntityTypes.OMINOUS_ITEM_SPAWNER$registryId] = simpleAddEntityHandler(CommonItemPacketHandler.INSTANCE); + this.handlers[MEntityTypes.OMINOUS_ITEM_SPAWNER$registryId] = simpleAddEntityHandler(ItemPacketHandler.INSTANCE); } this.handlers[MEntityTypes.FALLING_BLOCK$registryId] = (user, event) -> { FriendlyByteBuf buf = event.getBuffer(); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/handler/CommonItemPacketHandler.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/handler/CommonItemPacketHandler.java index b835c2c8f..4e264198e 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/handler/CommonItemPacketHandler.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/handler/CommonItemPacketHandler.java @@ -1,32 +1,16 @@ package net.momirealms.craftengine.bukkit.plugin.network.handler; -import net.kyori.adventure.text.Component; -import net.momirealms.craftengine.bukkit.entity.data.BaseEntityData; -import net.momirealms.craftengine.bukkit.entity.data.ItemEntityData; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; -import net.momirealms.craftengine.bukkit.util.ComponentUtils; import net.momirealms.craftengine.bukkit.util.EntityDataUtils; -import net.momirealms.craftengine.bukkit.world.score.BukkitTeamManager; import net.momirealms.craftengine.core.entity.player.Player; -import net.momirealms.craftengine.core.item.CustomItem; -import net.momirealms.craftengine.core.item.Item; -import net.momirealms.craftengine.core.item.ItemSettings; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.config.Config; -import net.momirealms.craftengine.core.plugin.context.ContextHolder; -import net.momirealms.craftengine.core.plugin.context.NetworkTextReplaceContext; -import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext; -import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters; import net.momirealms.craftengine.core.plugin.network.ByteBufPacketEvent; import net.momirealms.craftengine.core.plugin.network.EntityPacketHandler; -import net.momirealms.craftengine.core.plugin.text.minimessage.CustomTagResolver; -import net.momirealms.craftengine.core.util.AdventureHelper; -import net.momirealms.craftengine.core.util.ArrayUtils; import net.momirealms.craftengine.core.util.FriendlyByteBuf; -import net.momirealms.craftengine.core.util.LegacyChatFormatter; import org.bukkit.inventory.ItemStack; import java.util.List; @@ -43,104 +27,29 @@ public class CommonItemPacketHandler implements EntityPacketHandler { int id = buf.readVarInt(); boolean changed = false; List packedItems = FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$unpack(buf); - Component nameToShow = null; - LegacyChatFormatter glowColor = null; for (int i = 0; i < packedItems.size(); i++) { Object packedItem = packedItems.get(i); int entityDataId = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$id(packedItem); - if (entityDataId == EntityDataUtils.UNSAFE_ITEM_DATA_ID) { - Object nmsItemStack = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem); - - // 可能是其他插件导致的问题 - if (!CoreReflections.clazz$ItemStack.isInstance(nmsItemStack)) { - long time = System.currentTimeMillis(); - if (time - lastWarningTime > 5000) { - BukkitServerPlayer serverPlayer = (BukkitServerPlayer) user; - CraftEngine.instance().logger().severe("An issue was detected while applying item-related entity data for '" + serverPlayer.name() + - "'. Please execute the command '/ce debug entity-id " + serverPlayer.world().name() + " " + id + "' and provide a screenshot for further investigation."); - lastWarningTime = time; - } - continue; - } - - ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(nmsItemStack); - - // 转换为客户端侧物品 - Optional optional = BukkitItemManager.instance().s2c(itemStack, user); - if (optional.isPresent()) { - changed = true; - itemStack = optional.get(); - Object serializer = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$serializer(packedItem); - packedItems.set(i, FastNMS.INSTANCE.constructor$SynchedEntityData$DataValue(entityDataId, serializer, FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack))); - } - - // 处理 drop-display 物品设置 - // 一定要处理经历过客户端侧组件修改的物品 - Item wrappedItem = BukkitItemManager.instance().wrap(itemStack); - Optional> optionalCustomItem = wrappedItem.getCustomItem(); - String showName = null; - if (optionalCustomItem.isPresent()) { - ItemSettings settings = optionalCustomItem.get().settings(); - showName = settings.dropDisplay(); - glowColor = settings.glowColor(); - } else if (Config.enableDefaultDropDisplay()) { - showName = Config.defaultDropDisplayFormat(); - } - - // 如果设定了自定义展示名 - if (showName != null) { - PlayerOptionalContext context = NetworkTextReplaceContext.of(user, ContextHolder.builder() - .withParameter(DirectContextParameters.COUNT, itemStack.getAmount())); - Optional optionalHoverComponent = wrappedItem.hoverNameComponent(); - Component hoverComponent; - if (optionalHoverComponent.isPresent()) { - hoverComponent = optionalHoverComponent.get(); - } else { - hoverComponent = Component.translatable(itemStack.translationKey()); - } - // 展示名称为空,则显示其hover name - if (showName.isEmpty()) { - nameToShow = hoverComponent; - } - // 显示自定义格式的名字 - else { - nameToShow = AdventureHelper.miniMessage().deserialize( - showName, - ArrayUtils.appendElementToArrayTail(context.tagResolvers(), new CustomTagResolver("name", hoverComponent)) - ); - } + if (entityDataId != EntityDataUtils.UNSAFE_ITEM_DATA_ID) continue; + Object nmsItemStack = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem); + if (!CoreReflections.clazz$ItemStack.isInstance(nmsItemStack)) { + long time = System.currentTimeMillis(); + if (time - lastWarningTime > 5000) { + BukkitServerPlayer serverPlayer = (BukkitServerPlayer) user; + CraftEngine.instance().logger().severe("An issue was detected while applying item-related entity data for '" + serverPlayer.name() + + "'. Please execute the command '/ce debug entity-id " + serverPlayer.world().name() + " " + id + "' and provide a screenshot for further investigation."); + lastWarningTime = time; } + continue; } - } - if (glowColor != null) { - Object teamByColor = BukkitTeamManager.instance().getTeamByColor(glowColor); - if (teamByColor != null) { - changed = true; - outer: { - for (int i = 0; i < packedItems.size(); i++) { - Object packedItem = packedItems.get(i); - int entityDataId = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$id(packedItem); - if (entityDataId == BaseEntityData.SharedFlags.id()) { - byte flags = (Byte) FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem); - flags |= (byte) 0x40; - packedItems.set(i, BaseEntityData.SharedFlags.createEntityData(flags)); - break outer; - } - } - packedItems.add(BaseEntityData.SharedFlags.createEntityData((byte) 0x40)); - } - Object entityLookup = FastNMS.INSTANCE.method$ServerLevel$getEntityLookup(user.clientSideWorld().serverWorld()); - Object entity = FastNMS.INSTANCE.method$EntityLookup$get(entityLookup, id); - if (entity != null) { - user.sendPacket(FastNMS.INSTANCE.method$ClientboundSetPlayerTeamPacket$createMultiplePlayerPacket(teamByColor, List.of(FastNMS.INSTANCE.method$Entity$getUUID(entity).toString()), true), false); - } - } - } - // 添加自定义显示名 - if (nameToShow != null) { + ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(nmsItemStack); + Optional optional = BukkitItemManager.instance().s2c(itemStack, user); + if (optional.isEmpty()) continue; changed = true; - packedItems.add(ItemEntityData.CustomNameVisible.createEntityData(true)); - packedItems.add(ItemEntityData.CustomName.createEntityData(Optional.of(ComponentUtils.adventureToMinecraft(nameToShow)))); + itemStack = optional.get(); + Object serializer = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$serializer(packedItem); + packedItems.set(i, FastNMS.INSTANCE.constructor$SynchedEntityData$DataValue(entityDataId, serializer, FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack))); + break; } if (changed) { event.setChanged(true); @@ -150,4 +59,4 @@ public class CommonItemPacketHandler implements EntityPacketHandler { FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$pack(packedItems, buf); } } -} +} \ No newline at end of file diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/handler/ItemPacketHandler.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/handler/ItemPacketHandler.java new file mode 100644 index 000000000..6f01fdc82 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/handler/ItemPacketHandler.java @@ -0,0 +1,141 @@ +package net.momirealms.craftengine.bukkit.plugin.network.handler; + +import net.kyori.adventure.text.Component; +import net.momirealms.craftengine.bukkit.entity.data.BaseEntityData; +import net.momirealms.craftengine.bukkit.entity.data.ItemEntityData; +import net.momirealms.craftengine.bukkit.item.BukkitItemManager; +import net.momirealms.craftengine.bukkit.nms.FastNMS; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; +import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; +import net.momirealms.craftengine.bukkit.util.ComponentUtils; +import net.momirealms.craftengine.bukkit.util.EntityDataUtils; +import net.momirealms.craftengine.bukkit.world.score.BukkitTeamManager; +import net.momirealms.craftengine.core.entity.player.Player; +import net.momirealms.craftengine.core.item.CustomItem; +import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.item.ItemSettings; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.config.Config; +import net.momirealms.craftengine.core.plugin.context.ContextHolder; +import net.momirealms.craftengine.core.plugin.context.NetworkTextReplaceContext; +import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext; +import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters; +import net.momirealms.craftengine.core.plugin.network.ByteBufPacketEvent; +import net.momirealms.craftengine.core.plugin.network.EntityPacketHandler; +import net.momirealms.craftengine.core.plugin.text.minimessage.CustomTagResolver; +import net.momirealms.craftengine.core.util.AdventureHelper; +import net.momirealms.craftengine.core.util.ArrayUtils; +import net.momirealms.craftengine.core.util.FriendlyByteBuf; +import net.momirealms.craftengine.core.util.LegacyChatFormatter; +import org.bukkit.inventory.ItemStack; + +import java.util.List; +import java.util.Optional; + +public class ItemPacketHandler implements EntityPacketHandler { + public static final ItemPacketHandler INSTANCE = new ItemPacketHandler(); + + @Override + public void handleSetEntityData(Player user, ByteBufPacketEvent event) { + if (Config.disableItemOperations()) return; + FriendlyByteBuf buf = event.getBuffer(); + int id = buf.readVarInt(); + boolean changed = false; + List packedItems = FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$unpack(buf); + Component nameToShow = null; + LegacyChatFormatter glowColor = null; + for (int i = 0; i < packedItems.size(); i++) { + Object packedItem = packedItems.get(i); + int entityDataId = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$id(packedItem); + if (entityDataId == ItemEntityData.Item.id()) { + Object nmsItemStack = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem); + ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(nmsItemStack); + + // 转换为客户端侧物品 + Optional optional = BukkitItemManager.instance().s2c(itemStack, user); + if (optional.isPresent()) { + changed = true; + itemStack = optional.get(); + Object serializer = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$serializer(packedItem); + packedItems.set(i, FastNMS.INSTANCE.constructor$SynchedEntityData$DataValue(entityDataId, serializer, FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack))); + } + + // 处理 drop-display 物品设置 + // 一定要处理经历过客户端侧组件修改的物品 + Item wrappedItem = BukkitItemManager.instance().wrap(itemStack); + Optional> optionalCustomItem = wrappedItem.getCustomItem(); + String showName = null; + if (optionalCustomItem.isPresent()) { + ItemSettings settings = optionalCustomItem.get().settings(); + showName = settings.dropDisplay(); + glowColor = settings.glowColor(); + } else if (Config.enableDefaultDropDisplay()) { + showName = Config.defaultDropDisplayFormat(); + } + + // 如果设定了自定义展示名 + if (showName != null) { + PlayerOptionalContext context = NetworkTextReplaceContext.of(user, ContextHolder.builder() + .withParameter(DirectContextParameters.COUNT, itemStack.getAmount())); + Optional optionalHoverComponent = wrappedItem.hoverNameComponent(); + Component hoverComponent; + if (optionalHoverComponent.isPresent()) { + hoverComponent = optionalHoverComponent.get(); + } else { + hoverComponent = Component.translatable(itemStack.translationKey()); + } + // 展示名称为空,则显示其hover name + if (showName.isEmpty()) { + nameToShow = hoverComponent; + } + // 显示自定义格式的名字 + else { + nameToShow = AdventureHelper.miniMessage().deserialize( + showName, + ArrayUtils.appendElementToArrayTail(context.tagResolvers(), new CustomTagResolver("name", hoverComponent)) + ); + } + } + + break; + } + } + if (glowColor != null) { + Object teamByColor = BukkitTeamManager.instance().getTeamByColor(glowColor); + if (teamByColor != null) { + changed = true; + outer: { + for (int i = 0; i < packedItems.size(); i++) { + Object packedItem = packedItems.get(i); + int entityDataId = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$id(packedItem); + if (entityDataId == BaseEntityData.SharedFlags.id()) { + byte flags = (Byte) FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem); + flags |= (byte) 0x40; + packedItems.set(i, BaseEntityData.SharedFlags.createEntityData(flags)); + break outer; + } + } + packedItems.add(BaseEntityData.SharedFlags.createEntityData((byte) 0x40)); + } + Object entityLookup = FastNMS.INSTANCE.method$ServerLevel$getEntityLookup(user.clientSideWorld().serverWorld()); + Object entity = FastNMS.INSTANCE.method$EntityLookup$get(entityLookup, id); + if (entity != null) { + user.sendPacket(FastNMS.INSTANCE.method$ClientboundSetPlayerTeamPacket$createMultiplePlayerPacket(teamByColor, List.of(FastNMS.INSTANCE.method$Entity$getUUID(entity).toString()), true), false); + } + } + } + // 添加自定义显示名 + if (nameToShow != null) { + changed = true; + packedItems.add(ItemEntityData.CustomNameVisible.createEntityData(true)); + packedItems.add(ItemEntityData.CustomName.createEntityData(Optional.of(ComponentUtils.adventureToMinecraft(nameToShow)))); + } + if (changed) { + event.setChanged(true); + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeVarInt(id); + FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$pack(packedItems, buf); + } + } +}