From a2e9d2caf8cf6b18457f67334cfcf27d7872485d Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Thu, 3 Apr 2025 21:03:34 +0800 Subject: [PATCH] =?UTF-8?q?feat(network):=20=E5=AE=9E=E7=8E=B0=E6=96=B9?= =?UTF-8?q?=E5=9D=97=E5=B1=95=E7=A4=BA=E5=AE=9E=E4=BD=93=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E6=96=B9=E5=9D=97=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/network/BukkitNetworkManager.java | 1 + .../plugin/network/PacketConsumers.java | 37 +++++++++++++++++ .../craftengine/bukkit/util/Reflections.java | 41 +++++++++++++++++++ 3 files changed, 79 insertions(+) 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 d55ca3054..e095aba81 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 @@ -128,6 +128,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes registerNMSPacketConsumer(PacketConsumers.SIGN_UPDATE, Reflections.clazz$ServerboundSignUpdatePacket); registerNMSPacketConsumer(PacketConsumers.EDIT_BOOK, Reflections.clazz$ServerboundEditBookPacket); registerNMSPacketConsumer(PacketConsumers.CUSTOM_PAYLOAD, Reflections.clazz$ServerboundCustomPayloadPacket); + registerNMSPacketConsumer(PacketConsumers.SET_ENTITY_DATA, Reflections.clazz$ClientboundSetEntityDataPacket); registerByteBufPacketConsumer(PacketConsumers.SECTION_BLOCK_UPDATE, this.packetIds.clientboundSectionBlocksUpdatePacket()); registerByteBufPacketConsumer(PacketConsumers.BLOCK_UPDATE, this.packetIds.clientboundBlockUpdatePacket()); registerByteBufPacketConsumer(PacketConsumers.LEVEL_PARTICLE, this.packetIds.clientboundLevelParticlesPacket()); 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 0b2d8cdb9..78145a505 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 @@ -961,4 +961,41 @@ public class PacketConsumers { CraftEngine.instance().logger().warn("Failed to handle ServerboundCustomPayloadPacket", e); } }; + + @SuppressWarnings("unchecked") + public static final TriConsumer SET_ENTITY_DATA = (user, event, packet) -> { + try { + int id = (int) Reflections.field$ClientboundSetEntityDataPacket$id.get(packet); + Object player = user.serverPlayer(); + Object level = Reflections.method$Entity$level.invoke(player); + Object entityLookup = Reflections.method$Level$moonrise$getEntityLookup.invoke(level); + Object entity = Reflections.method$EntityLookup$get.invoke(entityLookup, id); + if (entity == null) return; + Object entityType = Reflections.method$Entity$getType.invoke(entity); + if (entityType != Reflections.instance$EntityType$BLOCK_DISPLAY) return; + List packedItems = (List) Reflections.field$ClientboundSetEntityDataPacket$packedItems.get(packet); + for (int i = 0; i < packedItems.size(); i++) { + Object packedItem = packedItems.get(i); + int entityDataId = (int) Reflections.field$SynchedEntityData$DataValue$id.get(packedItem); + if ((VersionHelper.isVersionNewerThan1_20_2() && entityDataId != 23) + || (!VersionHelper.isVersionNewerThan1_20_2() && entityDataId != 22)) { + continue; + } + Object blockState = Reflections.field$SynchedEntityData$DataValue$value.get(packedItem); + Object serializer = Reflections.field$SynchedEntityData$DataValue$serializer.get(packedItem); + int stateId = BlockStateUtils.blockStateToId(blockState); + int newStateId; + if (!user.clientModEnabled()) { + newStateId = remap(stateId); + } else { + newStateId = remapMOD(stateId); + } + packedItems.set(i, Reflections.constructor$SynchedEntityData$DataValue.newInstance( + entityDataId, serializer, BlockStateUtils.idToBlockState(newStateId) + )); + } + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundSetEntityDataPacket", e); + } + }; } 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 3da93b0fd..0a1abb9ca 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 @@ -809,6 +809,12 @@ public class Reflections { ) ); + public static final Field field$SynchedEntityData$DataValue$serializer = requireNonNull( + ReflectionUtils.getDeclaredField( + clazz$SynchedEntityData$DataValue, 1 + ) + ); + public static final Field field$SynchedEntityData$DataValue$value = requireNonNull( ReflectionUtils.getDeclaredField( clazz$SynchedEntityData$DataValue, 2 @@ -3666,6 +3672,7 @@ public class Reflections { public static final Object instance$EntityType$TEXT_DISPLAY; public static final Object instance$EntityType$ITEM_DISPLAY; + public static final Object instance$EntityType$BLOCK_DISPLAY; public static final Object instance$EntityType$FALLING_BLOCK; public static final Object instance$EntityType$INTERACTION; public static final Object instance$EntityType$SHULKER; @@ -3676,6 +3683,8 @@ public class Reflections { instance$EntityType$TEXT_DISPLAY = Reflections.method$Registry$get.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, textDisplay); Object itemDisplay = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "item_display"); instance$EntityType$ITEM_DISPLAY = Reflections.method$Registry$get.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, itemDisplay); + Object blockDisplay = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "block_display"); + instance$EntityType$BLOCK_DISPLAY = Reflections.method$Registry$get.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, blockDisplay); Object fallingBlock = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "falling_block"); instance$EntityType$FALLING_BLOCK = Reflections.method$Registry$get.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, fallingBlock); Object interaction = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "interaction"); @@ -6056,4 +6065,36 @@ public class Reflections { clazz$ClientboundMoveEntityPacket$Pos, int.class, short.class, short.class, short.class, boolean.class ) ); + + public static final Method method$Entity$getType = requireNonNull( + ReflectionUtils.getMethod( + clazz$Entity, clazz$EntityType + ) + ); + + public static final Constructor constructor$SynchedEntityData$DataValue = requireNonNull( + ReflectionUtils.getConstructor( + clazz$SynchedEntityData$DataValue, int.class, clazz$EntityDataSerializer, Object.class + ) + ); + + public static final Class clazz$EntityLookup = requireNonNull( + ReflectionUtils.getClazz( + "ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup", + "io.papermc.paper.chunk.system.entity.EntityLookup" + ) + ); + + public static final Method method$Level$moonrise$getEntityLookup = requireNonNull( + ReflectionUtils.getMethod( + VersionHelper.isVersionNewerThan1_21() ? clazz$Level : clazz$ServerLevel, + clazz$EntityLookup + ) + ); + + public static final Method method$EntityLookup$get = requireNonNull( + ReflectionUtils.getMethod( + clazz$EntityLookup, clazz$Entity, int.class + ) + ); }