From 29b0c9c8c5f6262daebc6fa873371c87b7434e97 Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Sat, 10 May 2025 13:51:03 +0800 Subject: [PATCH] =?UTF-8?q?refactor(bukkit):=20=E6=B7=BB=E5=8A=A0=E6=B0=B4?= =?UTF-8?q?=E4=B8=8B=E6=B0=94=E6=B3=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 准备设计配置格式 --- .../plugin/command/feature/TestCommand.java | 13 ------- .../plugin/network/BukkitNetworkManager.java | 3 +- .../plugin/network/PacketConsumers.java | 23 ++++++------ .../bukkit/util/CustomTridentUtils.java | 37 ++++++++++++++----- .../bukkit/util/ParticleUtils.java | 1 + .../craftengine/bukkit/util/Reflections.java | 30 ++++++++++++++- 6 files changed, 69 insertions(+), 38 deletions(-) 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 8cfc37e8a..c59ef90bd 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 @@ -42,7 +42,6 @@ public class TestCommand extends BukkitCommandFeature { public Command.Builder assembleCommand(org.incendo.cloud.CommandManager manager, Command.Builder builder) { return builder .senderType(Player.class) - .required("forceUpdate", BooleanParser.booleanParser()) .required("id", NamespacedKeyParser.namespacedKeyComponent().suggestionProvider(new SuggestionProvider<>() { @Override public @NonNull CompletableFuture> suggestionsFuture(@NonNull CommandContext context, @NonNull CommandInput input) { @@ -55,18 +54,6 @@ public class TestCommand extends BukkitCommandFeature { .required("rotationLeft", StringParser.stringParser()) .handler(context -> { Player player = context.sender(); - if (context.get("forceUpdate")) { - net.momirealms.craftengine.core.entity.player.Player cePlayer = plugin().adapt(player); - Collection tridents = player.getWorld().getEntitiesByClass(Trident.class); - List packets = new ArrayList<>(); - for (Trident trident : tridents) { - int entityId = FastNMS.INSTANCE.method$Entity$getId(FastNMS.INSTANCE.method$CraftEntity$getHandle(trident)); - player.sendMessage("COMMAND entityId: " + entityId); - packets.add(CustomTridentUtils.buildCustomTridentSetEntityDataPacket(cePlayer, entityId)); - } - cePlayer.sendPackets(packets, true); - return; - } NamespacedKey namespacedKey = context.get("id"); ItemStack item = new ItemStack(Material.TRIDENT); item.editMeta((meta) -> { 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 599364ad9..95bca0475 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 @@ -152,7 +152,6 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes registerNMSPacketConsumer(PacketConsumers.LOGIN_ACKNOWLEDGED, Reflections.clazz$ServerboundLoginAcknowledgedPacket); registerNMSPacketConsumer(PacketConsumers.RESOURCE_PACK_RESPONSE, Reflections.clazz$ServerboundResourcePackPacket); registerNMSPacketConsumer(PacketConsumers.ENTITY_EVENT, Reflections.clazz$ClientboundEntityEventPacket); - registerNMSPacketConsumer(PacketConsumers.SET_ENTITY_DATA, Reflections.clazz$ClientboundSetEntityDataPacket); registerNMSPacketConsumer(PacketConsumers.MOVE_ENTITY_ALL, Reflections.clazz$ClientboundMoveEntityPacket$PosRot); registerByteBufPacketConsumer(PacketConsumers.LEVEL_CHUNK_WITH_LIGHT, this.packetIds.clientboundLevelChunkWithLightPacket()); registerByteBufPacketConsumer(PacketConsumers.SECTION_BLOCK_UPDATE, this.packetIds.clientboundSectionBlocksUpdatePacket()); @@ -172,7 +171,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes registerByteBufPacketConsumer(PacketConsumers.REMOVE_ENTITY, this.packetIds.clientboundRemoveEntitiesPacket()); registerByteBufPacketConsumer(PacketConsumers.ADD_ENTITY_BYTEBUFFER, this.packetIds.clientboundAddEntityPacket()); registerByteBufPacketConsumer(PacketConsumers.SOUND, this.packetIds.clientboundSoundPacket()); - registerByteBufPacketConsumer(PacketConsumers.SET_ENTITY_DATA_BYTEBUFFER, this.packetIds.clientboundSetEntityDataPacket()); + registerByteBufPacketConsumer(PacketConsumers.SET_ENTITY_DATA, this.packetIds.clientboundSetEntityDataPacket()); } public static BukkitNetworkManager instance() { 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 4589fe4ab..0ab795316 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 @@ -2008,10 +2008,20 @@ public class PacketConsumers { }; @SuppressWarnings("unchecked") - public static final BiConsumer SET_ENTITY_DATA_BYTEBUFFER = (user, event) -> { + public static final BiConsumer SET_ENTITY_DATA = (user, event) -> { try { FriendlyByteBuf buf = event.getBuffer(); int id = buf.readVarInt(); + if (user.tridentView().containsKey(id)) { + List packedItems = FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$unpack(buf); + List newPackedItems = CustomTridentUtils.buildCustomTridentSetEntityDataPacket(user, packedItems, id); + event.setChanged(true); + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeVarInt(id); + FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$pack(newPackedItems, buf); + return; + } Object entityType = user.entityView().get(id); if (entityType == Reflections.instance$EntityType$BLOCK_DISPLAY) { boolean isChanged = false; @@ -2331,17 +2341,6 @@ public class PacketConsumers { } }; - public static final TriConsumer SET_ENTITY_DATA = (user, event, packet) -> { - try { - int entityId = Reflections.field$clazz$ClientboundSetEntityDataPacket$id.getInt(packet); - if (user.tridentView().containsKey(entityId)) { - CustomTridentUtils.modifyCustomTridentSetEntityData(user, event, entityId); - } - } catch (Exception e) { - CraftEngine.instance().logger().warn("Failed to handle ClientboundSetEntityDataPacket", e); - } - }; - public static final TriConsumer MOVE_ENTITY_ALL = (user, event, packet) -> { try { int entityId = BukkitInjector.internalFieldAccessor().field$ClientboundMoveEntityPacket$entityId(packet); 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 index 09a543a19..5c4c270e2 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/CustomTridentUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/CustomTridentUtils.java @@ -13,6 +13,7 @@ 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.World; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.entity.Trident; @@ -39,6 +40,8 @@ public class CustomTridentUtils { 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 (trident == null) return; + World world = trident.getWorld(); Object serverEntity; Object nmsEntity = FastNMS.INSTANCE.method$CraftEntity$getHandle(trident); Object tracker = Reflections.field$Entity$trackedEntity.get(nmsEntity); @@ -59,14 +62,26 @@ public class CustomTridentUtils { SchedulerTask task = CraftEngine.instance().scheduler().asyncRepeating(() -> { try { Reflections.method$ServerEntity$sendChanges.invoke(serverEntity); + if (!isInGround(nmsEntity)) { + world.spawnParticle(ParticleUtils.getParticle("BUBBLE"), trident.getLocation(), 1, 0, 0, 0, 0); + } } catch (IllegalAccessException | InvocationTargetException e) { CraftEngine.instance().logger().warn("Failed to send entity data packet", e); } - }, 5, 5, TimeUnit.MILLISECONDS); + }, 0, 5, TimeUnit.MILLISECONDS); user.tridentTaskView().put(entityId, task); } } + private static boolean isInGround(Object nmsEntity) throws IllegalAccessException, InvocationTargetException { + if (!Reflections.field$Entity$wasTouchingWater.getBoolean(nmsEntity)) return true; + if (VersionHelper.isOrAbove1_21_2()) { + return (boolean) Reflections.method$AbstractArrow$isInGround.invoke(nmsEntity); + } else { + return Reflections.field$AbstractArrow$inGround.getBoolean(nmsEntity); + } + } + @Nullable public static Trident getTridentById(NetWorkUser user, int entityId) { Player player = (Player) user.platformPlayer(); @@ -135,20 +150,22 @@ public class CustomTridentUtils { Reflections.field$ClientboundMoveEntityPacket$yRot.setByte(packet, MCUtils.packDegrees(-yRot)); } - public static Object buildCustomTridentSetEntityDataPacket(NetWorkUser user, int entityId) { + public static List buildCustomTridentSetEntityDataPacket(NetWorkUser user, List packedItems, int entityId) { + List newPackedItems = new ArrayList<>(); + for (Object packedItem : packedItems) { + int entityDataId = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$id(packedItem); + if (entityDataId < 8) { + newPackedItems.add(packedItem); + } + } List newData = user.tridentView().getOrDefault(entityId, List.of()); if (newData.isEmpty()) { Trident trident = getTridentById(user, entityId); - if (notCustomTrident(trident)) return null; + if (notCustomTrident(trident)) return newPackedItems; newData = buildEntityDataValues(trident); user.tridentView().put(entityId, newData); } - return FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId, newData); - } - - public static void modifyCustomTridentSetEntityData(NetWorkUser user, NMSPacketEvent event, int entityId) { - Object packet = buildCustomTridentSetEntityDataPacket(user, entityId); - if (packet == null) return; - event.replacePacket(packet); + newPackedItems.addAll(newData); + return newPackedItems; } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/ParticleUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/ParticleUtils.java index 6e847f6f9..e401be613 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/ParticleUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/ParticleUtils.java @@ -12,6 +12,7 @@ public class ParticleUtils { return switch (particle) { case "REDSTONE" -> Particle.valueOf("DUST"); case "VILLAGER_HAPPY", "HAPPY_VILLAGER" -> Particle.valueOf(VersionHelper.isOrAbove1_20_5() ? "HAPPY_VILLAGER" : "VILLAGER_HAPPY"); + case "BUBBLE" -> Particle.valueOf(VersionHelper.isOrAbove1_20_5() ? "BUBBLE" : "WATER_BUBBLE"); default -> Particle.valueOf(particle); }; } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java index 15fe735f3..d71b22597 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java @@ -6632,7 +6632,7 @@ public class Reflections { ) ); - public static final Field field$clazz$ClientboundSetEntityDataPacket$id = requireNonNull( + public static final Field field$ClientboundSetEntityDataPacket$id = requireNonNull( ReflectionUtils.getDeclaredField( clazz$ClientboundSetEntityDataPacket, int.class, 0 ) @@ -6730,4 +6730,32 @@ public class Reflections { clazz$ChunkMap$TrackedEntity, clazz$ServerEntity, 0 ) ); + + public static final Field field$Entity$wasTouchingWater = requireNonNull( + ReflectionUtils.getDeclaredField( + clazz$Entity, VersionHelper.isOrAbove1_21_2() + ? new String[]{ "wasTouchingWater", "ag" } : VersionHelper.isOrAbove1_20_5() + ? new String[]{ "wasTouchingWater", "aj" } : VersionHelper.isOrAbove1_20_2() + ? new String[]{ "wasTouchingWater", "ai" } : new String[]{ "wasTouchingWater", "ah" } + ) + ); + + public static final Class clazz$AbstractArrow = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.entity.projectile.EntityArrow", + "world.entity.projectile.AbstractArrow" + ) + ); + + // 1.20~1.21.1 + public static final Field field$AbstractArrow$inGround = + ReflectionUtils.getDeclaredField( + clazz$AbstractArrow, boolean.class, 0 + ); + + // 1.21.2+ + public static final Method method$AbstractArrow$isInGround = + ReflectionUtils.getMethod( + clazz$AbstractArrow, boolean.class, VersionHelper.isOrAbove1_21_5() ? new String[]{ "isInGround", "e" } : new String[]{ "isInGround", "l" } + ); }