From 5cfb418eb0e0b436272d76f1e9a90506dc7d1b9c Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Sat, 10 May 2025 02:37:44 +0800 Subject: [PATCH] =?UTF-8?q?refactor(bukkit):=20=E9=87=8D=E6=9E=84=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E4=B8=89=E5=8F=89=E6=88=9F=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/command/feature/TestCommand.java | 13 +- .../plugin/network/PacketConsumers.java | 76 +---------- .../bukkit/util/CustomTridentUtils.java | 118 ++++++++++++++++++ 3 files changed, 128 insertions(+), 79 deletions(-) create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/CustomTridentUtils.java diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java index a934709aa..368aab382 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java @@ -2,6 +2,7 @@ package net.momirealms.craftengine.bukkit.plugin.command.feature; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; +import net.momirealms.craftengine.bukkit.util.CustomTridentUtils; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager; @@ -54,20 +55,16 @@ public class TestCommand extends BukkitCommandFeature { Player player = context.sender(); NamespacedKey namespacedKey = context.get("id"); ItemStack item = new ItemStack(Material.TRIDENT); - NamespacedKey customTridentKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:custom_trident")); - NamespacedKey interpolationDelayKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:interpolation_delay")); - NamespacedKey transformationInterpolationDurationaKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:transformation_interpolation_duration")); - NamespacedKey positionRotationInterpolationDurationKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:position_rotation_interpolation_duration")); // NamespacedKey displayTypeKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:display_type")); // NamespacedKey customTridentX = Objects.requireNonNull(NamespacedKey.fromString("craftengine:custom_trident_x")); // NamespacedKey customTridentY = Objects.requireNonNull(NamespacedKey.fromString("craftengine:custom_trident_y")); // NamespacedKey customTridentZ = Objects.requireNonNull(NamespacedKey.fromString("craftengine:custom_trident_z")); // NamespacedKey customTridentW = Objects.requireNonNull(NamespacedKey.fromString("craftengine:custom_trident_w")); item.editMeta(meta -> { - meta.getPersistentDataContainer().set(customTridentKey, PersistentDataType.STRING, namespacedKey.asString()); - meta.getPersistentDataContainer().set(interpolationDelayKey, PersistentDataType.INTEGER, context.get("interpolationDelay")); - meta.getPersistentDataContainer().set(transformationInterpolationDurationaKey, PersistentDataType.INTEGER, context.get("transformationInterpolationDuration")); - meta.getPersistentDataContainer().set(positionRotationInterpolationDurationKey, PersistentDataType.INTEGER, context.get("positionRotationInterpolationDuration")); + meta.getPersistentDataContainer().set(CustomTridentUtils.customTridentKey, PersistentDataType.STRING, namespacedKey.asString()); + meta.getPersistentDataContainer().set(CustomTridentUtils.interpolationDelayKey, PersistentDataType.INTEGER, context.get("interpolationDelay")); + meta.getPersistentDataContainer().set(CustomTridentUtils.transformationInterpolationDurationaKey, PersistentDataType.INTEGER, context.get("transformationInterpolationDuration")); + meta.getPersistentDataContainer().set(CustomTridentUtils.positionRotationInterpolationDurationKey, PersistentDataType.INTEGER, context.get("positionRotationInterpolationDuration")); // container.set(displayTypeKey, PersistentDataType.BYTE, context.get("displayType")); // container.set(customTridentX, PersistentDataType.FLOAT, context.get("x")); // container.set(customTridentY, PersistentDataType.FLOAT, context.get("y")); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index a8e27c484..fc184bf1a 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -10,10 +10,8 @@ import net.momirealms.craftengine.bukkit.api.CraftEngineFurniture; import net.momirealms.craftengine.bukkit.api.event.FurnitureBreakEvent; import net.momirealms.craftengine.bukkit.api.event.FurnitureInteractEvent; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; -import net.momirealms.craftengine.bukkit.entity.data.ItemDisplayEntityData; import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager; import net.momirealms.craftengine.bukkit.entity.furniture.LoadedFurniture; -import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.item.behavior.FurnitureItemBehavior; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.pack.BukkitPackManager; @@ -52,16 +50,11 @@ import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; import org.bukkit.entity.Player; -import org.bukkit.entity.Trident; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; -import org.bukkit.persistence.PersistentDataContainer; -import org.bukkit.persistence.PersistentDataType; import org.bukkit.util.RayTraceResult; import org.bukkit.util.Vector; import org.jetbrains.annotations.Nullable; -import org.joml.Quaternionf; -import org.joml.Vector3f; import java.lang.reflect.InvocationTargetException; import java.nio.charset.StandardCharsets; @@ -1615,45 +1608,7 @@ public class PacketConsumers { event.setCancelled(true); } } else if (entityType == Reflections.instance$EntityType$TRIDENT) { - int entityId = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$entityId(packet); - Player player = (Player) user.platformPlayer(); - Trident trident = (Trident) FastNMS.INSTANCE.getBukkitEntityById(player.getWorld(), entityId); - PersistentDataContainer container = trident.getItemStack().getItemMeta().getPersistentDataContainer(); - NamespacedKey customTridentKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:custom_trident")); - String customTrident = container.get(customTridentKey, PersistentDataType.STRING); - if (customTrident == null) return; - user.tridentView().put(entityId, List.of()); - NamespacedKey interpolationDelayKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:interpolation_delay")); - NamespacedKey transformationInterpolationDurationaKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:transformation_interpolation_duration")); - NamespacedKey positionRotationInterpolationDurationKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:position_rotation_interpolation_duration")); - Integer interpolationDelay = container.get(interpolationDelayKey, PersistentDataType.INTEGER); - Integer transformationInterpolationDuration = container.get(transformationInterpolationDurationaKey, PersistentDataType.INTEGER); - Integer positionRotationInterpolationDuration = container.get(positionRotationInterpolationDurationKey, PersistentDataType.INTEGER); - float yRot = MCUtils.unpackDegrees(Reflections.field$ClientboundAddEntityPacket$yRot.getByte(packet)); - float xRot = MCUtils.unpackDegrees(Reflections.field$ClientboundAddEntityPacket$xRot.getByte(packet)); - player.sendMessage("加载自定义三叉戟实体1: " + packet); - Reflections.field$ClientboundAddEntityPacket$type.set(packet, Reflections.instance$EntityType$ITEM_DISPLAY); - Reflections.field$ClientboundAddEntityPacket$yRot.setByte(packet, MCUtils.packDegrees(-yRot)); - Reflections.field$ClientboundAddEntityPacket$xRot.setByte(packet, MCUtils.packDegrees(Math.clamp(-xRot, -90.0F, 90.0F))); - List itemDisplayValues = new ArrayList<>(); - Item item = BukkitItemManager.instance().createWrappedItem(Key.of(customTrident), null); - ItemDisplayEntityData.InterpolationDelay.addEntityDataIfNotDefaultValue(interpolationDelay, itemDisplayValues); - ItemDisplayEntityData.Translation.addEntityDataIfNotDefaultValue(new Vector3f(0, 0, -2), itemDisplayValues); - ItemDisplayEntityData.RotationLeft.addEntityDataIfNotDefaultValue(new Quaternionf(1, 1, 1, 1), itemDisplayValues); - if (VersionHelper.isOrAbove1_20_2()) { - ItemDisplayEntityData.TransformationInterpolationDuration.addEntityDataIfNotDefaultValue(transformationInterpolationDuration, itemDisplayValues); - ItemDisplayEntityData.PositionRotationInterpolationDuration.addEntityDataIfNotDefaultValue(positionRotationInterpolationDuration, itemDisplayValues); - } else { - ItemDisplayEntityData.InterpolationDuration.addEntityDataIfNotDefaultValue(transformationInterpolationDuration, itemDisplayValues); - } - ItemDisplayEntityData.DisplayedItem.addEntityDataIfNotDefaultValue(item.getLiteralObject(), itemDisplayValues); - ItemDisplayEntityData.DisplayType.addEntityDataIfNotDefaultValue((byte) 0, itemDisplayValues); - user.tridentView().put(entityId, itemDisplayValues); - player.sendMessage("加载自定义三叉戟实体2: " + entityId); - event.addDelayedTask(() -> { - user.sendPacket(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId, itemDisplayValues), true); - player.sendMessage("加载自定义三叉戟实体3: " + itemDisplayValues); - }); + CustomTridentUtils.handleCustomTrident(user, event, packet); } } catch (Exception e) { CraftEngine.instance().logger().warn("Failed to handle ClientboundAddEntityPacket", e); @@ -1665,16 +1620,7 @@ public class PacketConsumers { try { int entityId = FastNMS.INSTANCE.method$ClientboundEntityPositionSyncPacket$id(packet); if (user.tridentView().containsKey(entityId)) { - Player player = (Player) user.platformPlayer(); - player.sendMessage("同步三叉戟实体位置: " + packet); - Object positionMoveRotation = Reflections.field$ClientboundEntityPositionSyncPacket$values.get(packet); - boolean onGround = Reflections.field$ClientboundEntityPositionSyncPacket$onGround.getBoolean(packet); - Object position = Reflections.field$PositionMoveRotation$position.get(positionMoveRotation); - Object deltaMovement = Reflections.field$PositionMoveRotation$deltaMovement.get(positionMoveRotation); - float yRot = Reflections.field$PositionMoveRotation$yRot.getFloat(positionMoveRotation); - float xRot = Reflections.field$PositionMoveRotation$xRot.getFloat(positionMoveRotation); - Object newPositionMoveRotation = Reflections.constructor$PositionMoveRotation.newInstance(position, deltaMovement, -yRot, Math.clamp(-xRot, -90.0F, 90.0F)); - event.replacePacket(Reflections.constructor$ClientboundEntityPositionSyncPacket.newInstance(entityId, newPositionMoveRotation, onGround)); + CustomTridentUtils.modifyCustomTridentPositionSync(event, packet, entityId); return; } if (BukkitFurnitureManager.instance().isFurnitureRealEntity(entityId)) { @@ -1705,11 +1651,7 @@ public class PacketConsumers { int entityId = intList.getInt(i); user.entityView().remove(entityId); List entities = user.furnitureView().remove(entityId); - var removeTrident = user.tridentView().remove(entityId); - if (removeTrident != null && !removeTrident.isEmpty()) { - Player player = (Player) user.platformPlayer(); - player.sendMessage("移除三叉戟实体: " + removeTrident); - } + user.tridentView().remove(entityId); if (entities == null) continue; for (int subEntityId : entities) { isChange = true; @@ -2388,10 +2330,7 @@ public class PacketConsumers { try { int entityId = Reflections.field$clazz$ClientboundSetEntityDataPacket$id.getInt(packet); if (user.tridentView().containsKey(entityId)) { - Player player = (Player) user.platformPlayer(); - Object newPacket = FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId, user.tridentView().get(entityId)); - player.sendMessage("设置三叉戟实体数据: " + newPacket); - event.replacePacket(newPacket); + CustomTridentUtils.modifyCustomTridentSetEntityData(user, event, entityId); } } catch (Exception e) { CraftEngine.instance().logger().warn("Failed to handle ClientboundSetEntityDataPacket", e); @@ -2402,12 +2341,7 @@ public class PacketConsumers { try { int entityId = BukkitInjector.internalFieldAccessor().field$ClientboundMoveEntityPacket$entityId(packet); if (user.tridentView().containsKey(entityId)) { - float xRot = MCUtils.unpackDegrees(Reflections.field$ClientboundMoveEntityPacket$xRot.getByte(packet)); - float yRot = MCUtils.unpackDegrees(Reflections.field$ClientboundMoveEntityPacket$yRot.getByte(packet)); - Reflections.field$ClientboundMoveEntityPacket$xRot.setByte(packet, MCUtils.packDegrees(Math.clamp(-xRot, -90.0F, 90.0F))); - Reflections.field$ClientboundMoveEntityPacket$yRot.setByte(packet, MCUtils.packDegrees(-yRot)); - Player player = (Player) user.platformPlayer(); - player.sendMessage("同步三叉戟实体位置: " + Math.clamp(-xRot, -90.0F, 90.0F) + ", " + -yRot); + CustomTridentUtils.modifyCustomTridentMove(packet); } } catch (Exception e) { CraftEngine.instance().logger().warn("Failed to handle ClientboundMoveEntityPacket$PosRot", e); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/CustomTridentUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/CustomTridentUtils.java new file mode 100644 index 000000000..761b411e2 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/CustomTridentUtils.java @@ -0,0 +1,118 @@ +package net.momirealms.craftengine.bukkit.util; + +import net.momirealms.craftengine.bukkit.entity.data.ItemDisplayEntityData; +import net.momirealms.craftengine.bukkit.item.BukkitItemManager; +import net.momirealms.craftengine.bukkit.nms.FastNMS; +import net.momirealms.craftengine.bukkit.plugin.network.NMSPacketEvent; +import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.plugin.network.NetWorkUser; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.MCUtils; +import net.momirealms.craftengine.core.util.VersionHelper; +import org.bukkit.NamespacedKey; +import org.bukkit.entity.Player; +import org.bukkit.entity.Trident; +import org.bukkit.inventory.ItemStack; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; +import org.joml.Quaternionf; +import org.joml.Vector3f; + +import javax.annotation.Nullable; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class CustomTridentUtils { + public static final NamespacedKey customTridentKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:custom_trident")); + public static final NamespacedKey interpolationDelayKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:interpolation_delay")); + public static final NamespacedKey transformationInterpolationDurationaKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:transformation_interpolation_duration")); + public static final NamespacedKey positionRotationInterpolationDurationKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:position_rotation_interpolation_duration")); + + public static void handleCustomTrident(NetWorkUser user, NMSPacketEvent event, Object packet) throws IllegalAccessException { + int entityId = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$entityId(packet); + Trident trident = getTridentById(user, entityId); + if (!isCustomTrident(trident)) return; + user.tridentView().put(entityId, List.of()); + modifyCustomTridentPacket(packet); + List itemDisplayValues = buildEntityDataValues(trident); + user.tridentView().put(entityId, itemDisplayValues); + event.addDelayedTask(() -> { + user.sendPacket(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId, itemDisplayValues), true); + }); + } + + @Nullable + public static Trident getTridentById(NetWorkUser user, int entityId) { + Player player = (Player) user.platformPlayer(); + return (Trident) FastNMS.INSTANCE.getBukkitEntityById(player.getWorld(), entityId); + } + + public static boolean isCustomTrident(Trident trident) { + if (trident == null) return false; + PersistentDataContainer container = trident.getItemStack().getItemMeta().getPersistentDataContainer(); + String customTrident = container.get(customTridentKey, PersistentDataType.STRING); + return customTrident != null; + } + + public static void modifyCustomTridentPacket(Object packet) throws IllegalAccessException { + float yRot = MCUtils.unpackDegrees(Reflections.field$ClientboundAddEntityPacket$yRot.getByte(packet)); + float xRot = MCUtils.unpackDegrees(Reflections.field$ClientboundAddEntityPacket$xRot.getByte(packet)); + Reflections.field$ClientboundAddEntityPacket$type.set(packet, Reflections.instance$EntityType$ITEM_DISPLAY); + Reflections.field$ClientboundAddEntityPacket$yRot.setByte(packet, MCUtils.packDegrees(-yRot)); + Reflections.field$ClientboundAddEntityPacket$xRot.setByte(packet, MCUtils.packDegrees(Math.clamp(-xRot, -90.0F, 90.0F))); + } + + public static List buildEntityDataValues(Trident trident) { + List itemDisplayValues = new ArrayList<>(); + PersistentDataContainer container = trident.getItemStack().getItemMeta().getPersistentDataContainer(); + String customTrident = container.get(customTridentKey, PersistentDataType.STRING); + Item item = BukkitItemManager.instance().createWrappedItem(Key.of(customTrident), null); + Integer interpolationDelay = container.get(interpolationDelayKey, PersistentDataType.INTEGER); + Integer transformationInterpolationDuration = container.get(transformationInterpolationDurationaKey, PersistentDataType.INTEGER); + Integer positionRotationInterpolationDuration = container.get(positionRotationInterpolationDurationKey, PersistentDataType.INTEGER); + ItemDisplayEntityData.InterpolationDelay.addEntityDataIfNotDefaultValue(interpolationDelay, itemDisplayValues); + ItemDisplayEntityData.Translation.addEntityDataIfNotDefaultValue(new Vector3f(0, 0, -2), itemDisplayValues); + ItemDisplayEntityData.RotationLeft.addEntityDataIfNotDefaultValue(new Quaternionf(1, 1, 1, 1), itemDisplayValues); + if (VersionHelper.isOrAbove1_20_2()) { + ItemDisplayEntityData.TransformationInterpolationDuration.addEntityDataIfNotDefaultValue(transformationInterpolationDuration, itemDisplayValues); + ItemDisplayEntityData.PositionRotationInterpolationDuration.addEntityDataIfNotDefaultValue(positionRotationInterpolationDuration, itemDisplayValues); + } else { + ItemDisplayEntityData.InterpolationDuration.addEntityDataIfNotDefaultValue(transformationInterpolationDuration, itemDisplayValues); + } + ItemDisplayEntityData.DisplayedItem.addEntityDataIfNotDefaultValue(item.getLiteralObject(), itemDisplayValues); + ItemDisplayEntityData.DisplayType.addEntityDataIfNotDefaultValue((byte) 0, itemDisplayValues); + return itemDisplayValues; + } + + // 这里需要补 ClientboundMoveEntityPacket 包 1.21.2+ + public static void modifyCustomTridentPositionSync(NMSPacketEvent event, Object packet, int entityId) throws IllegalAccessException, InvocationTargetException, InstantiationException { + Object positionMoveRotation = Reflections.field$ClientboundEntityPositionSyncPacket$values.get(packet); + boolean onGround = Reflections.field$ClientboundEntityPositionSyncPacket$onGround.getBoolean(packet); + Object position = Reflections.field$PositionMoveRotation$position.get(positionMoveRotation); + Object deltaMovement = Reflections.field$PositionMoveRotation$deltaMovement.get(positionMoveRotation); + float yRot = Reflections.field$PositionMoveRotation$yRot.getFloat(positionMoveRotation); + float xRot = Reflections.field$PositionMoveRotation$xRot.getFloat(positionMoveRotation); + Object newPositionMoveRotation = Reflections.constructor$PositionMoveRotation.newInstance(position, deltaMovement, -yRot, Math.clamp(-xRot, -90.0F, 90.0F)); + event.replacePacket(Reflections.constructor$ClientboundEntityPositionSyncPacket.newInstance(entityId, newPositionMoveRotation, onGround)); + } + + public static void modifyCustomTridentMove(Object packet) throws IllegalAccessException { + float xRot = MCUtils.unpackDegrees(Reflections.field$ClientboundMoveEntityPacket$xRot.getByte(packet)); + float yRot = MCUtils.unpackDegrees(Reflections.field$ClientboundMoveEntityPacket$yRot.getByte(packet)); + Reflections.field$ClientboundMoveEntityPacket$xRot.setByte(packet, MCUtils.packDegrees(Math.clamp(-xRot, -90.0F, 90.0F))); + Reflections.field$ClientboundMoveEntityPacket$yRot.setByte(packet, MCUtils.packDegrees(-yRot)); + } + + public static void modifyCustomTridentSetEntityData(NetWorkUser user, NMSPacketEvent event, int entityId) { + List newData = user.tridentView().get(entityId); + if (newData.isEmpty()) { + Trident trident = getTridentById(user, entityId); + if (!isCustomTrident(trident)) return; + newData = buildEntityDataValues(trident); + user.tridentView().put(entityId, newData); + } + event.replacePacket(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId, newData)); + } +}