From ff7da2d9428e37d14b4e04a7e2210547f62c4ffc Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Wed, 2 Apr 2025 15:51:50 +0800 Subject: [PATCH 01/19] =?UTF-8?q?fix(bukkit):=20=E9=98=BB=E6=AD=A2?= =?UTF-8?q?=E5=8F=91=E9=80=81=E4=BB=85=E5=AE=9E=E4=BD=93=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/entity/furniture/BukkitFurnitureManager.java | 4 ++++ .../bukkit/plugin/network/BukkitNetworkManager.java | 1 + .../craftengine/bukkit/plugin/network/PacketConsumers.java | 3 +++ 3 files changed, 8 insertions(+) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java index 3066082fb..d2d48310d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java @@ -277,6 +277,10 @@ public class BukkitFurnitureManager implements FurnitureManager { return this.furnitureByCollisionEntitiesId.get(entityId); } + public boolean isFurnitureCollisionEntity(int entityId) { + return this.furnitureByCollisionEntitiesId.containsKey(entityId); + } + protected void handleBaseFurnitureUnload(Entity entity) { int id = entity.getEntityId(); LoadedFurniture furniture = this.furnitureByBaseEntityId.remove(id); 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 c87622e84..b5f4b4db2 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 @@ -450,6 +450,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes NMSPacketEvent event = new NMSPacketEvent(packet); onNMSPacketSend(player, event, packet); if (event.isCancelled()) return; + System.out.println("Packet sent: " + packet); super.write(context, packet, channelPromise); channelPromise.addListener((p) -> { for (Runnable task : event.getDelayedTasks()) { 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 c8ec39fe2..388c8553f 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 @@ -644,6 +644,9 @@ public class PacketConsumers { if (BukkitFurnitureManager.instance().isFurnitureBaseEntity(entityId)) { event.setCancelled(true); } + if (BukkitFurnitureManager.instance().isFurnitureCollisionEntity(entityId)) { + event.setCancelled(true); + } } catch (Exception e) { CraftEngine.instance().logger().warn("Failed to handle ClientboundEntityPositionSyncPacket", e); } From aacf82d523c8561737b5765d1f35050812f6d33c Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Wed, 2 Apr 2025 15:58:48 +0800 Subject: [PATCH 02/19] =?UTF-8?q?fix(bukkit):=20=E9=98=BB=E6=AD=A2?= =?UTF-8?q?=E5=8F=91=E9=80=81=E4=BB=85=E6=9C=8D=E5=8A=A1=E7=AB=AF=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../craftengine/bukkit/plugin/network/PacketConsumers.java | 3 +++ 1 file changed, 3 insertions(+) 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 388c8553f..23bd23cde 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 @@ -658,6 +658,9 @@ public class PacketConsumers { if (BukkitFurnitureManager.instance().isFurnitureBaseEntity(entityId)) { event.setCancelled(true); } + if (BukkitFurnitureManager.instance().isFurnitureCollisionEntity(entityId)) { + event.setCancelled(true); + } } catch (Exception e) { CraftEngine.instance().logger().warn("Failed to handle ClientboundMoveEntityPacket$Pos", e); } From 1279597a1a678097e8d060848c32cc549f401bd7 Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Wed, 2 Apr 2025 16:07:18 +0800 Subject: [PATCH 03/19] =?UTF-8?q?fix(bukkit):=20=E4=BF=AE=E5=A4=8DShulker?= =?UTF-8?q?=20=E4=BA=A4=E4=BA=92=E5=AE=9E=E4=BD=93=E9=AB=98=E5=BA=A6?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/furniture/hitbox/ShulkerHitBox.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java index f4bcbebb7..fa1878850 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java @@ -44,11 +44,23 @@ public class ShulkerHitBox extends AbstractHitBox { if (this.interactionEntity) { // make it a litter bigger - InteractionEntityData.Height.addEntityDataIfNotDefaultValue(getPhysicalPeek(peek * 0.01F) * scale + 1.01f, cachedInteractionValues); + InteractionEntityData.Height.addEntityDataIfNotDefaultValue((float) (getHeight(peek, scale, direction) + 0.01f), cachedInteractionValues); InteractionEntityData.Width.addEntityDataIfNotDefaultValue(scale + 0.005f, cachedInteractionValues); InteractionEntityData.Responsive.addEntityDataIfNotDefaultValue(interactive, cachedInteractionValues); } } + private static double getHeight(byte inPeek, float scale, Direction direction) { + float peek = getPhysicalPeek(inPeek * 0.01F); + double y1 = 0.0; + double y2 = scale; + double dy = (double) direction.stepY() * peek * (double) scale; + if (dy > 0) { + y2 += dy; + } else if (dy < 0) { + y1 += dy; + } + return y2 - y1; + } @Override public Optional optionalCollider() { From 73f77aacdef84d315fc48d56e33e1be42d3afaad Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Wed, 2 Apr 2025 16:24:18 +0800 Subject: [PATCH 04/19] =?UTF-8?q?fix(bukkit):=20=E9=98=BB=E6=AD=A2?= =?UTF-8?q?=E5=8F=91=E9=80=81=E4=BB=85=E6=9C=8D=E5=8A=A1=E7=AB=AF=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/network/BukkitNetworkManager.java | 3 ++ .../plugin/network/PacketConsumers.java | 42 +++++++++++++++++++ .../craftengine/bukkit/util/Reflections.java | 33 +++++++++++++++ 3 files changed, 78 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 b5f4b4db2..65dd8ff2a 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 @@ -134,6 +134,9 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes registerNMSPacketConsumer(PacketConsumers.REMOVE_ENTITY, Reflections.clazz$ClientboundRemoveEntitiesPacket); registerNMSPacketConsumer(PacketConsumers.SYNC_ENTITY_POSITION, Reflections.clazz$ClientboundEntityPositionSyncPacket); registerNMSPacketConsumer(PacketConsumers.MOVE_ENTITY, Reflections.clazz$ClientboundMoveEntityPacket$Pos); + registerNMSPacketConsumer(PacketConsumers.MOVE_AND_ROTATION_ENTITY, Reflections.clazz$ClientboundMoveEntityPacket$PosRot); + registerNMSPacketConsumer(PacketConsumers.ROTATE_HEAD, Reflections.clazz$ClientboundRotateHeadPacket); + registerNMSPacketConsumer(PacketConsumers.SET_ENTITY_MOTION, Reflections.clazz$ClientboundSetEntityMotionPacket); registerNMSPacketConsumer(PacketConsumers.PICK_ITEM_FROM_ENTITY, Reflections.clazz$ServerboundPickItemFromEntityPacket); registerNMSPacketConsumer(PacketConsumers.SOUND, Reflections.clazz$ClientboundSoundPacket); registerNMSPacketConsumer(PacketConsumers.RENAME_ITEM, Reflections.clazz$ServerboundRenameItemPacket); 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 23bd23cde..1faa248e9 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 @@ -666,6 +666,48 @@ public class PacketConsumers { } }; + public static final TriConsumer MOVE_AND_ROTATION_ENTITY = (user, event, packet) -> { + try { + int entityId = (int) Reflections.field$ClientboundMoveEntityPacket$entityId.get(packet); + if (BukkitFurnitureManager.instance().isFurnitureBaseEntity(entityId)) { + event.setCancelled(true); + } + if (BukkitFurnitureManager.instance().isFurnitureCollisionEntity(entityId)) { + event.setCancelled(true); + } + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundMoveEntityPacket$PosRot", e); + } + }; + + public static final TriConsumer ROTATE_HEAD = (user, event, packet) -> { + try { + int entityId = (int) Reflections.field$ClientboundRotateHeadPacket$entityId.get(packet); + if (BukkitFurnitureManager.instance().isFurnitureBaseEntity(entityId)) { + event.setCancelled(true); + } + if (BukkitFurnitureManager.instance().isFurnitureCollisionEntity(entityId)) { + event.setCancelled(true); + } + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundRotateHeadPacket", e); + } + }; + + public static final TriConsumer SET_ENTITY_MOTION = (user, event, packet) -> { + try { + int entityId = (int) Reflections.field$ClientboundSetEntityMotionPacket$id.get(packet); + if (BukkitFurnitureManager.instance().isFurnitureBaseEntity(entityId)) { + event.setCancelled(true); + } + if (BukkitFurnitureManager.instance().isFurnitureCollisionEntity(entityId)) { + event.setCancelled(true); + } + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundSetEntityMotionPacket", e); + } + }; + public static final TriConsumer REMOVE_ENTITY = (user, event, packet) -> { try { IntList intList = (IntList) Reflections.field$ClientboundRemoveEntitiesPacket$entityIds.get(packet); 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 16ecc73d9..860171138 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 @@ -5930,4 +5930,37 @@ public class Reflections { ? ReflectionUtils.getMethod(clazz$Entity, int.class, new String[]{"af"}) : ReflectionUtils.getMethod(clazz$Entity, int.class, new String[]{"getId", "aj", "ah", "af"}) ); + + public static final Class clazz$ClientboundMoveEntityPacket$PosRot = requireNonNull( + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundMoveEntityPacket$PosRot"), + BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutEntity$PacketPlayOutRelEntityMoveLook") + ) + ); + + public static final Class clazz$ClientboundRotateHeadPacket = requireNonNull( + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundRotateHeadPacket"), + BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutEntityHeadRotation") + ) + ); + + public static final Field field$ClientboundRotateHeadPacket$entityId = requireNonNull( + ReflectionUtils.getDeclaredField( + clazz$ClientboundRotateHeadPacket, int.class, 0 + ) + ); + + public static final Class clazz$ClientboundSetEntityMotionPacket = requireNonNull( + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundSetEntityMotionPacket"), + BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutEntityVelocity") + ) + ); + + public static final Field field$ClientboundSetEntityMotionPacket$id = requireNonNull( + ReflectionUtils.getDeclaredField( + clazz$ClientboundSetEntityMotionPacket, int.class, 0 + ) + ); } From c1b4384d6b275ccfe888c661af3fcd6a7f453528 Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Wed, 2 Apr 2025 16:33:40 +0800 Subject: [PATCH 05/19] =?UTF-8?q?fix(bukkit):=20=E9=98=BB=E6=AD=A2?= =?UTF-8?q?=E5=8F=91=E9=80=81=E4=BB=85=E6=9C=8D=E5=8A=A1=E7=AB=AF=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/network/BukkitNetworkManager.java | 3 -- .../plugin/network/PacketConsumers.java | 42 ------------------- 2 files changed, 45 deletions(-) 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 65dd8ff2a..b5f4b4db2 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 @@ -134,9 +134,6 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes registerNMSPacketConsumer(PacketConsumers.REMOVE_ENTITY, Reflections.clazz$ClientboundRemoveEntitiesPacket); registerNMSPacketConsumer(PacketConsumers.SYNC_ENTITY_POSITION, Reflections.clazz$ClientboundEntityPositionSyncPacket); registerNMSPacketConsumer(PacketConsumers.MOVE_ENTITY, Reflections.clazz$ClientboundMoveEntityPacket$Pos); - registerNMSPacketConsumer(PacketConsumers.MOVE_AND_ROTATION_ENTITY, Reflections.clazz$ClientboundMoveEntityPacket$PosRot); - registerNMSPacketConsumer(PacketConsumers.ROTATE_HEAD, Reflections.clazz$ClientboundRotateHeadPacket); - registerNMSPacketConsumer(PacketConsumers.SET_ENTITY_MOTION, Reflections.clazz$ClientboundSetEntityMotionPacket); registerNMSPacketConsumer(PacketConsumers.PICK_ITEM_FROM_ENTITY, Reflections.clazz$ServerboundPickItemFromEntityPacket); registerNMSPacketConsumer(PacketConsumers.SOUND, Reflections.clazz$ClientboundSoundPacket); registerNMSPacketConsumer(PacketConsumers.RENAME_ITEM, Reflections.clazz$ServerboundRenameItemPacket); 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 1faa248e9..23bd23cde 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 @@ -666,48 +666,6 @@ public class PacketConsumers { } }; - public static final TriConsumer MOVE_AND_ROTATION_ENTITY = (user, event, packet) -> { - try { - int entityId = (int) Reflections.field$ClientboundMoveEntityPacket$entityId.get(packet); - if (BukkitFurnitureManager.instance().isFurnitureBaseEntity(entityId)) { - event.setCancelled(true); - } - if (BukkitFurnitureManager.instance().isFurnitureCollisionEntity(entityId)) { - event.setCancelled(true); - } - } catch (Exception e) { - CraftEngine.instance().logger().warn("Failed to handle ClientboundMoveEntityPacket$PosRot", e); - } - }; - - public static final TriConsumer ROTATE_HEAD = (user, event, packet) -> { - try { - int entityId = (int) Reflections.field$ClientboundRotateHeadPacket$entityId.get(packet); - if (BukkitFurnitureManager.instance().isFurnitureBaseEntity(entityId)) { - event.setCancelled(true); - } - if (BukkitFurnitureManager.instance().isFurnitureCollisionEntity(entityId)) { - event.setCancelled(true); - } - } catch (Exception e) { - CraftEngine.instance().logger().warn("Failed to handle ClientboundRotateHeadPacket", e); - } - }; - - public static final TriConsumer SET_ENTITY_MOTION = (user, event, packet) -> { - try { - int entityId = (int) Reflections.field$ClientboundSetEntityMotionPacket$id.get(packet); - if (BukkitFurnitureManager.instance().isFurnitureBaseEntity(entityId)) { - event.setCancelled(true); - } - if (BukkitFurnitureManager.instance().isFurnitureCollisionEntity(entityId)) { - event.setCancelled(true); - } - } catch (Exception e) { - CraftEngine.instance().logger().warn("Failed to handle ClientboundSetEntityMotionPacket", e); - } - }; - public static final TriConsumer REMOVE_ENTITY = (user, event, packet) -> { try { IntList intList = (IntList) Reflections.field$ClientboundRemoveEntitiesPacket$entityIds.get(packet); From 0b9db0bd87635c1a1948c6edc06b7bcaf010ce87 Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Wed, 2 Apr 2025 16:35:19 +0800 Subject: [PATCH 06/19] =?UTF-8?q?fix(bukkit):=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E8=B0=83=E8=AF=95=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../craftengine/bukkit/plugin/network/BukkitNetworkManager.java | 1 - 1 file changed, 1 deletion(-) 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 b5f4b4db2..c87622e84 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 @@ -450,7 +450,6 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes NMSPacketEvent event = new NMSPacketEvent(packet); onNMSPacketSend(player, event, packet); if (event.isCancelled()) return; - System.out.println("Packet sent: " + packet); super.write(context, packet, channelPromise); channelPromise.addListener((p) -> { for (Runnable task : event.getDelayedTasks()) { From 5ac33bfb5ef1a71547e80f45bb9bf15d02217ae1 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Wed, 2 Apr 2025 16:37:23 +0800 Subject: [PATCH 07/19] fix hitbox --- .../bukkit/entity/furniture/LoadedFurniture.java | 1 + .../entity/furniture/hitbox/ShulkerHitBox.java | 2 +- .../craftengine/core/font/EmojiManager.java | 9 --------- gradle.properties | 14 +++++++------- 4 files changed, 9 insertions(+), 17 deletions(-) delete mode 100644 core/src/main/java/net/momirealms/craftengine/core/font/EmojiManager.java diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java index 90841f3e7..36d76dec5 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java @@ -126,6 +126,7 @@ public class LoadedFurniture { if (colliderSize != 0) { Object world = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(this.location.getWorld()); for (int i = 0; i < colliderSize; i++) { + // TODO better shulker hitbox Collider collider = placement.colliders()[i]; Vector3f offset = conjugated.transform(new Vector3f(collider.position())); Vector3d offset1 = collider.point1(); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java index f4bcbebb7..f4d61ad0d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java @@ -44,7 +44,7 @@ public class ShulkerHitBox extends AbstractHitBox { if (this.interactionEntity) { // make it a litter bigger - InteractionEntityData.Height.addEntityDataIfNotDefaultValue(getPhysicalPeek(peek * 0.01F) * scale + 1.01f, cachedInteractionValues); + InteractionEntityData.Height.addEntityDataIfNotDefaultValue((getPhysicalPeek(peek * 0.01F) + 1) * scale + 0.01f, cachedInteractionValues); InteractionEntityData.Width.addEntityDataIfNotDefaultValue(scale + 0.005f, cachedInteractionValues); InteractionEntityData.Responsive.addEntityDataIfNotDefaultValue(interactive, cachedInteractionValues); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/font/EmojiManager.java b/core/src/main/java/net/momirealms/craftengine/core/font/EmojiManager.java deleted file mode 100644 index 868846fd6..000000000 --- a/core/src/main/java/net/momirealms/craftengine/core/font/EmojiManager.java +++ /dev/null @@ -1,9 +0,0 @@ -package net.momirealms.craftengine.core.font; - -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; - -public interface EmojiManager extends ConfigSectionParser { - String CONFIG_SECTION_NAME = "emojis"; - - -} diff --git a/gradle.properties b/gradle.properties index 0d5805a02..f05f586d7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -49,7 +49,7 @@ mojang_brigadier_version=1.0.18 byte_buddy_version=1.15.11 snake_yaml_version=2.3 anti_grief_version=0.13 -nms_helper_version=0.28 +nms_helper_version=0.29 # Ignite Dependencies mixinextras_version=0.4.1 mixin_version=0.15.2+mixin.0.8.7 @@ -63,9 +63,9 @@ modmenu_version=13.0.3 cloth_version=17.0.144 # Proxy settings -#systemProp.socks.proxyHost=127.0.0.1 -#systemProp.socks.proxyPort=7890 -#systemProp.http.proxyHost=127.0.0.1 -#systemProp.http.proxyPort=7890 -#systemProp.https.proxyHost=127.0.0.1 -#systemProp.https.proxyPort=7890 \ No newline at end of file +systemProp.socks.proxyHost=127.0.0.1 +systemProp.socks.proxyPort=7890 +systemProp.http.proxyHost=127.0.0.1 +systemProp.http.proxyPort=7890 +systemProp.https.proxyHost=127.0.0.1 +systemProp.https.proxyPort=7890 \ No newline at end of file From 5c56b82acee50ecbaf8d79caf0aed3c1cefc7cdc Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Wed, 2 Apr 2025 16:37:43 +0800 Subject: [PATCH 08/19] Update gradle.properties --- gradle.properties | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gradle.properties b/gradle.properties index f05f586d7..cc5ca5e33 100644 --- a/gradle.properties +++ b/gradle.properties @@ -63,9 +63,9 @@ modmenu_version=13.0.3 cloth_version=17.0.144 # Proxy settings -systemProp.socks.proxyHost=127.0.0.1 -systemProp.socks.proxyPort=7890 -systemProp.http.proxyHost=127.0.0.1 -systemProp.http.proxyPort=7890 -systemProp.https.proxyHost=127.0.0.1 -systemProp.https.proxyPort=7890 \ No newline at end of file +#systemProp.socks.proxyHost=127.0.0.1 +#systemProp.socks.proxyPort=7890 +#systemProp.http.proxyHost=127.0.0.1 +#systemProp.http.proxyPort=7890 +#systemProp.https.proxyHost=127.0.0.1 +#systemProp.https.proxyPort=7890 \ No newline at end of file From 2dd078517961026f754edca2d13ed25c38d163a8 Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Wed, 2 Apr 2025 16:49:31 +0800 Subject: [PATCH 09/19] =?UTF-8?q?fix(bukkit):=20=E4=BF=AE=E5=A4=8D=20MOD?= =?UTF-8?q?=20=E6=96=B9=E5=9D=97=E7=8A=B6=E6=80=81=20ID=20=E6=98=A0?= =?UTF-8?q?=E5=B0=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../craftengine/bukkit/plugin/network/PacketConsumers.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 23bd23cde..007854ac8 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 @@ -70,7 +70,8 @@ public class PacketConsumers { } public static int remapMOD(int stateId) { - return mappingsMOD[stateId]; + int modStateId = mappingsMOD[stateId]; + return BlockStateUtils.isVanillaBlock(modStateId) ? remap(modStateId) : modStateId; } public static final TriConsumer LEVEL_CHUNK_WITH_LIGHT = (user, event, packet) -> { From 70cf61d9edff67a687cc528be2debfd1dfae0519 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Wed, 2 Apr 2025 20:22:11 +0800 Subject: [PATCH 10/19] faster nms --- .../bukkit/api/CraftEngineBlocks.java | 4 +- .../bukkit/block/BlockEventListener.java | 7 +- .../block/behavior/BukkitBlockBehavior.java | 121 ++++++++++++++++ .../block/behavior/BushBlockBehavior.java | 8 +- .../behavior/ConcretePowderBlockBehavior.java | 8 +- .../block/behavior/CropBlockBehavior.java | 10 +- .../block/behavior/FallingBlockBehavior.java | 8 +- .../block/behavior/HangingBlockBehavior.java | 6 +- .../block/behavior/LeavesBlockBehavior.java | 8 +- .../block/behavior/OnLiquidBlockBehavior.java | 6 +- .../block/behavior/SaplingBlockBehavior.java | 12 +- .../behavior/StrippableBlockBehavior.java | 8 +- .../behavior/SugarCaneBlockBehavior.java | 14 +- .../behavior/WaterLoggedBlockBehavior.java | 8 +- .../entity/furniture/LoadedFurniture.java | 4 +- .../item/behavior/BlockItemBehavior.java | 2 +- .../item/recipe/RecipeEventListener.java | 3 +- .../plugin/command/feature/TestCommand.java | 9 +- .../plugin/injector/BukkitInjector.java | 40 ++++- .../plugin/network/BukkitNetworkManager.java | 34 +---- .../plugin/network/PacketConsumers.java | 4 +- .../bukkit/util/DirectionUtils.java | 9 ++ .../craftengine/bukkit/util/LightUtils.java | 24 ++- .../craftengine/bukkit/util/MirrorUtils.java | 31 ++++ .../util/NoteBlockChainUpdateUtils.java | 2 +- .../craftengine/bukkit/util/Reflections.java | 137 ++++++++++++++---- .../bukkit/util/RotationUtils.java | 34 +++++ .../craftengine/bukkit/world/BukkitWorld.java | 4 +- .../bukkit/world/BukkitWorldBlock.java | 3 +- .../block/behavior/AbstractBlockBehavior.java | 6 + gradle.properties | 2 +- .../craftengine/mod/CraftEngineBlock.java | 27 +++- .../shared/block/BlockBehavior.java | 8 + 33 files changed, 458 insertions(+), 153 deletions(-) create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BukkitBlockBehavior.java create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/MirrorUtils.java create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/RotationUtils.java diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java index ed4dc7d2e..79a27fcc7 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java @@ -108,11 +108,11 @@ public final class CraftEngineBlocks { boolean playSound) { boolean success; try { - Object worldServer = Reflections.field$CraftWorld$ServerLevel.get(location.getWorld()); + Object worldServer = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(location.getWorld()); Object blockPos = FastNMS.INSTANCE.constructor$BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()); Object blockState = block.customBlockState().handle(); Object oldBlockState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(worldServer, blockPos); - success = (boolean) Reflections.method$LevelWriter$setBlock.invoke(worldServer, blockPos, blockState, option.flags()); + success = FastNMS.INSTANCE.method$LevelWriter$setBlock(worldServer, blockPos, blockState, option.flags()); if (success) { Reflections.method$BlockStateBase$onPlace.invoke(blockState, worldServer, blockPos, oldBlockState, true); if (playSound) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java index befb9a1e2..32449e5d6 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java @@ -2,6 +2,7 @@ package net.momirealms.craftengine.bukkit.block; import io.papermc.paper.event.block.BlockBreakBlockEvent; import net.momirealms.craftengine.bukkit.api.event.CustomBlockBreakEvent; +import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; import net.momirealms.craftengine.bukkit.util.*; @@ -316,10 +317,10 @@ public class BlockEventListener implements Listener { Block sourceBlock = event.getSourceBlock(); BlockFace direction = sourceBlock.getFace(block); if (direction == BlockFace.UP || direction == BlockFace.DOWN) { - Object serverLevel = Reflections.field$CraftWorld$ServerLevel.get(world); - Object chunkSource = Reflections.field$ServerLevel$chunkSource.get(serverLevel); + Object serverLevel = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(world); + Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(serverLevel); Object blockPos = LocationUtils.toBlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()); - Reflections.method$ServerChunkCache$blockChanged.invoke(chunkSource, blockPos); + FastNMS.INSTANCE.method$ServerChunkCache$blockChanged(chunkSource, blockPos); if (direction == BlockFace.UP) { NoteBlockChainUpdateUtils.noteBlockChainUpdate(serverLevel, chunkSource, Reflections.instance$Direction$UP, blockPos, 0); } else { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BukkitBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BukkitBlockBehavior.java new file mode 100644 index 000000000..93ad23eb6 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BukkitBlockBehavior.java @@ -0,0 +1,121 @@ +package net.momirealms.craftengine.bukkit.block.behavior; + +import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; +import net.momirealms.craftengine.bukkit.util.BlockStateUtils; +import net.momirealms.craftengine.bukkit.util.MirrorUtils; +import net.momirealms.craftengine.bukkit.util.RotationUtils; +import net.momirealms.craftengine.core.block.CustomBlock; +import net.momirealms.craftengine.core.block.ImmutableBlockState; +import net.momirealms.craftengine.core.block.behavior.AbstractBlockBehavior; +import net.momirealms.craftengine.core.block.properties.Property; +import net.momirealms.craftengine.core.util.Direction; +import net.momirealms.craftengine.core.util.HorizontalDirection; +import net.momirealms.craftengine.core.util.Mirror; +import net.momirealms.craftengine.core.util.Rotation; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.Callable; +import java.util.function.BiConsumer; + +public class BukkitBlockBehavior extends AbstractBlockBehavior { + private static final Map>> HARD_CODED_PROPERTY_DATA = new HashMap<>(); + static { + HARD_CODED_PROPERTY_DATA.put("axis", (behavior, property) -> { + @SuppressWarnings("unchecked") + Property axisProperty = (Property) property; + behavior.rotateFunction = (thisBlock, blockState, rotation) -> { + Direction.Axis axis = blockState.get(axisProperty); + return switch (rotation) { + case COUNTERCLOCKWISE_90, CLOCKWISE_90 -> switch (axis) { + case X -> blockState.with(axisProperty, Direction.Axis.Z).customBlockState().handle(); + case Z -> blockState.with(axisProperty, Direction.Axis.X).customBlockState().handle(); + default -> blockState.customBlockState().handle(); + }; + default -> blockState.customBlockState().handle(); + }; + }; + }); + HARD_CODED_PROPERTY_DATA.put("facing", (behavior, property) -> { + if (property.valueClass() == HorizontalDirection.class) { + @SuppressWarnings("unchecked") + Property directionProperty = (Property) property; + behavior.rotateFunction = (thisBlock, blockState, rotation) -> + blockState.with(directionProperty, rotation.rotate(blockState.get(directionProperty).toDirection()).toHorizontalDirection()) + .customBlockState().handle(); + behavior.mirrorFunction = (thisBlock, blockState, mirror) -> { + Rotation rotation = mirror.getRotation(blockState.get(directionProperty).toDirection()); + return behavior.rotateFunction.rotate(thisBlock, blockState, rotation); + }; + } else if (property.valueClass() == Direction.class) { + @SuppressWarnings("unchecked") + Property directionProperty = (Property) property; + behavior.rotateFunction = (thisBlock, blockState, rotation) -> + blockState.with(directionProperty, rotation.rotate(blockState.get(directionProperty))) + .customBlockState().handle(); + behavior.mirrorFunction = (thisBlock, blockState, mirror) -> { + Rotation rotation = mirror.getRotation(blockState.get(directionProperty)); + return behavior.rotateFunction.rotate(thisBlock, blockState, rotation); + }; + } + }); + HARD_CODED_PROPERTY_DATA.put("facing_clockwise", (behavior, property) -> { + if (property.valueClass() == Direction.class) { + @SuppressWarnings("unchecked") + Property directionProperty = (Property) property; + behavior.rotateFunction = (thisBlock, blockState, rotation) -> + blockState.with(directionProperty, rotation.rotate(blockState.get(directionProperty))) + .customBlockState().handle(); + behavior.mirrorFunction = (thisBlock, blockState, mirror) -> { + Rotation rotation = mirror.getRotation(blockState.get(directionProperty)); + return behavior.rotateFunction.rotate(thisBlock, blockState, rotation); + }; + } + }); + } + + private MirrorFunction mirrorFunction; + private RotateFunction rotateFunction; + + public BukkitBlockBehavior(CustomBlock customBlock) { + super(customBlock); + for (Property property : customBlock.properties()) { + Optional.ofNullable(HARD_CODED_PROPERTY_DATA.get(property.name())).ifPresent( + c -> c.accept(this, property) + ); + } + } + + @Override + public Object mirror(Object thisBlock, Object[] args, Callable superMethod) throws Exception { + if (this.mirrorFunction != null) { + int id = BlockStateUtils.blockStateToId(args[0]); + ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(id); + return this.mirrorFunction.mirror(thisBlock, state, MirrorUtils.fromNMSMirror(args[1])); + } + return super.mirror(thisBlock, args, superMethod); + } + + @Override + public Object rotate(Object thisBlock, Object[] args, Callable superMethod) throws Exception { + if (this.rotateFunction != null) { + int id = BlockStateUtils.blockStateToId(args[0]); + ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(id); + return this.rotateFunction.rotate(thisBlock, state, RotationUtils.fromNMSRotation(args[1])); + } + return super.rotate(thisBlock, args, superMethod); + } + + @FunctionalInterface + interface MirrorFunction { + + Object mirror(Object thisBlock, ImmutableBlockState state, Mirror mirror) throws Exception; + } + + @FunctionalInterface + interface RotateFunction { + + Object rotate(Object thisBlock, ImmutableBlockState state, Rotation rotation) throws Exception; + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java index 13b6e32ae..7c42b3ad8 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java @@ -9,7 +9,6 @@ import net.momirealms.craftengine.bukkit.util.Reflections; import net.momirealms.craftengine.bukkit.world.BukkitWorld; import net.momirealms.craftengine.core.block.CustomBlock; import net.momirealms.craftengine.core.block.ImmutableBlockState; -import net.momirealms.craftengine.core.block.behavior.AbstractBlockBehavior; import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.loot.parameter.LootParameters; @@ -29,14 +28,15 @@ import org.bukkit.Registry; import java.util.*; import java.util.concurrent.Callable; -public class BushBlockBehavior extends AbstractBlockBehavior { +public class BushBlockBehavior extends BukkitBlockBehavior { public static final Factory FACTORY = new Factory(); protected final List tagsCanSurviveOn; protected final Set blocksCansSurviveOn; protected final Set customBlocksCansSurviveOn; protected final boolean any; - public BushBlockBehavior(List tagsCanSurviveOn, Set blocksCansSurviveOn, Set customBlocksCansSurviveOn) { + public BushBlockBehavior(CustomBlock block, List tagsCanSurviveOn, Set blocksCansSurviveOn, Set customBlocksCansSurviveOn) { + super(block); this.tagsCanSurviveOn = tagsCanSurviveOn; this.blocksCansSurviveOn = blocksCansSurviveOn; this.customBlocksCansSurviveOn = customBlocksCansSurviveOn; @@ -93,7 +93,7 @@ public class BushBlockBehavior extends AbstractBlockBehavior { @Override public BlockBehavior create(CustomBlock block, Map arguments) { Tuple, Set, Set> tuple = readTagsAndState(arguments); - return new BushBlockBehavior(tuple.left(), tuple.mid(), tuple.right()); + return new BushBlockBehavior(block, tuple.left(), tuple.mid(), tuple.right()); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java index 3df82844d..2f79abc20 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java @@ -32,9 +32,9 @@ public class ConcretePowderBlockBehavior extends FallingBlockBehavior { private Object defaultBlockState; private ImmutableBlockState defaultImmutableBlockState; - public ConcretePowderBlockBehavior(float hurtAmount, int maxHurt, Key block) { - super(hurtAmount, maxHurt); - this.targetBlock = block; + public ConcretePowderBlockBehavior(CustomBlock block, float hurtAmount, int maxHurt, Key targetBlock) { + super(block, hurtAmount, maxHurt); + this.targetBlock = targetBlock; } public ImmutableBlockState defaultImmutableBlockState() { @@ -161,7 +161,7 @@ public class ConcretePowderBlockBehavior extends FallingBlockBehavior { if (solidBlock == null) { throw new IllegalArgumentException("No `solid-block` specified for concrete powder block behavior"); } - return new ConcretePowderBlockBehavior(hurtAmount, hurtMax, Key.of(solidBlock)); + return new ConcretePowderBlockBehavior(block, hurtAmount, hurtMax, Key.of(solidBlock)); } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/CropBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/CropBlockBehavior.java index b4cde1bd8..a8b8881fd 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/CropBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/CropBlockBehavior.java @@ -29,9 +29,9 @@ public class CropBlockBehavior extends BushBlockBehavior { private final float growSpeed; private final int minGrowLight; - public CropBlockBehavior(List tagsCanSurviveOn, Set blocksCansSurviveOn, Set customBlocksCansSurviveOn, + public CropBlockBehavior(CustomBlock block, List tagsCanSurviveOn, Set blocksCansSurviveOn, Set customBlocksCansSurviveOn, Property ageProperty, float growSpeed, int minGrowLight) { - super(tagsCanSurviveOn, blocksCansSurviveOn, customBlocksCansSurviveOn); + super(block, tagsCanSurviveOn, blocksCansSurviveOn, customBlocksCansSurviveOn); this.ageProperty = (IntegerProperty) ageProperty; this.growSpeed = growSpeed; this.minGrowLight = minGrowLight; @@ -63,7 +63,7 @@ public class CropBlockBehavior extends BushBlockBehavior { if (currentState != null && !currentState.isEmpty()) { int age = this.getAge(currentState); if (age < this.ageProperty.max && RandomUtils.generateRandomFloat(0, 1) < this.growSpeed) { - Reflections.method$Level$setBlock.invoke(level, pos, currentState.with(this.ageProperty, age + 1).customBlockState().handle(), UpdateOption.UPDATE_ALL.flags()); + FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, currentState.with(this.ageProperty, age + 1).customBlockState().handle(), UpdateOption.UPDATE_ALL.flags()); } } } @@ -117,7 +117,7 @@ public class CropBlockBehavior extends BushBlockBehavior { if (i > maxAge) { i = maxAge; } - Reflections.method$Level$setBlock.invoke(level, pos, immutableBlockState.with(this.ageProperty, i).customBlockState().handle(), UpdateOption.UPDATE_NONE.flags()); + FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, immutableBlockState.with(this.ageProperty, i).customBlockState().handle(), UpdateOption.UPDATE_NONE.flags()); if (sendParticles) { World world = FastNMS.INSTANCE.method$Level$getCraftWorld(level); int x = FastNMS.INSTANCE.field$Vec3i$x(pos); @@ -140,7 +140,7 @@ public class CropBlockBehavior extends BushBlockBehavior { // 存活条件是最小生长亮度-1 int minGrowLight = MiscUtils.getAsInt(arguments.getOrDefault("light-requirement", 9)); float growSpeed = MiscUtils.getAsFloat(arguments.getOrDefault("grow-speed", 0.25f)); - return new CropBlockBehavior(tuple.left(), tuple.mid(), tuple.right(), ageProperty, growSpeed, minGrowLight); + return new CropBlockBehavior(block, tuple.left(), tuple.mid(), tuple.right(), ageProperty, growSpeed, minGrowLight); } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FallingBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FallingBlockBehavior.java index 08bbc708a..8b2813ea9 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FallingBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FallingBlockBehavior.java @@ -8,7 +8,6 @@ import net.momirealms.craftengine.bukkit.util.Reflections; import net.momirealms.craftengine.bukkit.world.BukkitWorld; import net.momirealms.craftengine.core.block.CustomBlock; import net.momirealms.craftengine.core.block.ImmutableBlockState; -import net.momirealms.craftengine.core.block.behavior.AbstractBlockBehavior; import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.loot.parameter.LootParameters; @@ -21,12 +20,13 @@ import net.momirealms.craftengine.shared.block.BlockBehavior; import java.util.Map; import java.util.concurrent.Callable; -public class FallingBlockBehavior extends AbstractBlockBehavior { +public class FallingBlockBehavior extends BukkitBlockBehavior { public static final Factory FACTORY = new Factory(); private final float hurtAmount; private final int maxHurt; - public FallingBlockBehavior(float hurtAmount, int maxHurt) { + public FallingBlockBehavior(CustomBlock block, float hurtAmount, int maxHurt) { + super(block); this.hurtAmount = hurtAmount; this.maxHurt = maxHurt; } @@ -131,7 +131,7 @@ public class FallingBlockBehavior extends AbstractBlockBehavior { public BlockBehavior create(CustomBlock block, Map arguments) { float hurtAmount = MiscUtils.getAsFloat(arguments.getOrDefault("hurt-amount", -1f)); int hurtMax = MiscUtils.getAsInt(arguments.getOrDefault("max-hurt", -1)); - return new FallingBlockBehavior(hurtAmount, hurtMax); + return new FallingBlockBehavior(block, hurtAmount, hurtMax); } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/HangingBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/HangingBlockBehavior.java index 2c43e4ea8..2d802ed2b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/HangingBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/HangingBlockBehavior.java @@ -13,8 +13,8 @@ import java.util.Set; public class HangingBlockBehavior extends BushBlockBehavior { public static final Factory FACTORY = new Factory(); - public HangingBlockBehavior(List tagsCanSurviveOn, Set blocksCansSurviveOn, Set customBlocksCansSurviveOn) { - super(tagsCanSurviveOn, blocksCansSurviveOn, customBlocksCansSurviveOn); + public HangingBlockBehavior(CustomBlock block, List tagsCanSurviveOn, Set blocksCansSurviveOn, Set customBlocksCansSurviveOn) { + super(block, tagsCanSurviveOn, blocksCansSurviveOn, customBlocksCansSurviveOn); } @Override @@ -32,7 +32,7 @@ public class HangingBlockBehavior extends BushBlockBehavior { @Override public BlockBehavior create(CustomBlock block, Map arguments) { Tuple, Set, Set> tuple = readTagsAndState(arguments); - return new HangingBlockBehavior(tuple.left(), tuple.mid(), tuple.right()); + return new HangingBlockBehavior(block, tuple.left(), tuple.mid(), tuple.right()); } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LeavesBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LeavesBlockBehavior.java index d454b2c1b..99b543466 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LeavesBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LeavesBlockBehavior.java @@ -39,8 +39,8 @@ public class LeavesBlockBehavior extends WaterLoggedBlockBehavior { @Nullable private final Property waterloggedProperty; - public LeavesBlockBehavior(int maxDistance, Property distanceProperty, Property persistentProperty, @Nullable Property waterloggedProperty) { - super(waterloggedProperty); + public LeavesBlockBehavior(CustomBlock block, int maxDistance, Property distanceProperty, Property persistentProperty, @Nullable Property waterloggedProperty) { + super(block, waterloggedProperty); this.maxDistance = maxDistance; this.distanceProperty = distanceProperty; this.persistentProperty = persistentProperty; @@ -97,7 +97,7 @@ public class LeavesBlockBehavior extends WaterLoggedBlockBehavior { if (blockState == newState.customBlockState().handle()) { Reflections.method$BlockStateBase$updateNeighbourShapes.invoke(blockState, level, blockPos, UpdateOption.UPDATE_ALL.flags(), 512); } else { - Reflections.method$Level$setBlock.invoke(level, blockPos, newState.customBlockState().handle(), UpdateOption.UPDATE_ALL.flags()); + FastNMS.INSTANCE.method$LevelWriter$setBlock(level, blockPos, newState.customBlockState().handle(), UpdateOption.UPDATE_ALL.flags()); } } } @@ -182,7 +182,7 @@ public class LeavesBlockBehavior extends WaterLoggedBlockBehavior { } Property waterlogged = (Property) block.getProperty("waterlogged"); int actual = distance.possibleValues().get(distance.possibleValues().size() - 1); - return new LeavesBlockBehavior(actual, distance, persistent, waterlogged); + return new LeavesBlockBehavior(block, actual, distance, persistent, waterlogged); } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/OnLiquidBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/OnLiquidBlockBehavior.java index cb5934a2e..dda596013 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/OnLiquidBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/OnLiquidBlockBehavior.java @@ -16,8 +16,8 @@ public class OnLiquidBlockBehavior extends BushBlockBehavior { private final boolean onWater; private final boolean onLava; - public OnLiquidBlockBehavior(boolean onWater, boolean onLava) { - super(List.of(), Set.of(), Set.of()); + public OnLiquidBlockBehavior(CustomBlock block, boolean onWater, boolean onLava) { + super(block, List.of(), Set.of(), Set.of()); this.onWater = onWater; this.onLava = onLava; } @@ -34,7 +34,7 @@ public class OnLiquidBlockBehavior extends BushBlockBehavior { @Override public BlockBehavior create(CustomBlock block, Map arguments) { List liquidTypes = MiscUtils.getAsStringList(arguments.getOrDefault("liquid-type", List.of("water"))); - return new OnLiquidBlockBehavior(liquidTypes.contains("water"), liquidTypes.contains("lava")); + return new OnLiquidBlockBehavior(block, liquidTypes.contains("water"), liquidTypes.contains("lava")); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SaplingBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SaplingBlockBehavior.java index 04df34dc8..e985c3d24 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SaplingBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SaplingBlockBehavior.java @@ -31,8 +31,8 @@ public class SaplingBlockBehavior extends BushBlockBehavior { private final double boneMealSuccessChance; private final float growSpeed; - public SaplingBlockBehavior(Key feature, Property stageProperty, List tagsCanSurviveOn, Set blocksCansSurviveOn, Set customBlocksCansSurviveOn, double boneMealSuccessChance, float growSpeed) { - super(tagsCanSurviveOn, blocksCansSurviveOn, customBlocksCansSurviveOn); + public SaplingBlockBehavior(CustomBlock block, Key feature, Property stageProperty, List tagsCanSurviveOn, Set blocksCansSurviveOn, Set customBlocksCansSurviveOn, double boneMealSuccessChance, float growSpeed) { + super(block, tagsCanSurviveOn, blocksCansSurviveOn, customBlocksCansSurviveOn); this.feature = feature; this.stageProperty = stageProperty; this.boneMealSuccessChance = boneMealSuccessChance; @@ -79,18 +79,18 @@ public class SaplingBlockBehavior extends BushBlockBehavior { CraftEngine.instance().logger().warn("Configured feature not found: " + treeFeature()); return; } - Object chunkGenerator = Reflections.method$ServerChunkCache$getGenerator.invoke(Reflections.field$ServerLevel$chunkSource.get(world)); + Object chunkGenerator = Reflections.method$ServerChunkCache$getGenerator.invoke(FastNMS.INSTANCE.method$ServerLevel$getChunkSource(world)); Object configuredFeature = Reflections.method$Holder$value.invoke(holder.get()); Object fluidState = Reflections.method$Level$getFluidState.invoke(world, blockPos); Object legacyState = Reflections.method$FluidState$createLegacyBlock.invoke(fluidState); - Reflections.method$Level$setBlock.invoke(world, blockPos, legacyState, UpdateOption.UPDATE_NONE.flags()); + FastNMS.INSTANCE.method$LevelWriter$setBlock(world, blockPos, legacyState, UpdateOption.UPDATE_NONE.flags()); if ((boolean) Reflections.method$ConfiguredFeature$place.invoke(configuredFeature, world, chunkGenerator, randomSource, blockPos)) { if (FastNMS.INSTANCE.method$BlockGetter$getBlockState(world, blockPos) == legacyState) { Reflections.method$ServerLevel$sendBlockUpdated.invoke(world, blockPos, blockState, legacyState, 2); } } else { // failed to place, rollback changes - Reflections.method$Level$setBlock.invoke(world, blockPos, blockState, UpdateOption.UPDATE_NONE.flags()); + FastNMS.INSTANCE.method$LevelWriter$setBlock(world, blockPos, blockState, UpdateOption.UPDATE_NONE.flags()); } } @@ -150,7 +150,7 @@ public class SaplingBlockBehavior extends BushBlockBehavior { } double boneMealSuccessChance = MiscUtils.getAsDouble(arguments.getOrDefault("bone-meal-success-chance", 0.45)); Tuple, Set, Set> tuple = readTagsAndState(arguments); - return new SaplingBlockBehavior(Key.of(feature), stageProperty, tuple.left(), tuple.mid(), tuple.right(), boneMealSuccessChance, + return new SaplingBlockBehavior(block, Key.of(feature), stageProperty, tuple.left(), tuple.mid(), tuple.right(), boneMealSuccessChance, MiscUtils.getAsFloat(arguments.getOrDefault("grow-speed", 1.0 / 7.0))); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/StrippableBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/StrippableBlockBehavior.java index 6d0429c37..6a5d4ee7f 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/StrippableBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/StrippableBlockBehavior.java @@ -1,18 +1,18 @@ package net.momirealms.craftengine.bukkit.block.behavior; import net.momirealms.craftengine.core.block.CustomBlock; -import net.momirealms.craftengine.core.block.behavior.AbstractBlockBehavior; import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.shared.block.BlockBehavior; import java.util.Map; -public class StrippableBlockBehavior extends AbstractBlockBehavior { +public class StrippableBlockBehavior extends BukkitBlockBehavior { public static final Factory FACTORY = new Factory(); private final Key stripped; - public StrippableBlockBehavior(Key stripped) { + public StrippableBlockBehavior(CustomBlock block, Key stripped) { + super(block); this.stripped = stripped; } @@ -28,7 +28,7 @@ public class StrippableBlockBehavior extends AbstractBlockBehavior { if (stripped == null) { throw new IllegalArgumentException("stripped is null"); } - return new StrippableBlockBehavior(Key.of(stripped)); + return new StrippableBlockBehavior(block, Key.of(stripped)); } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SugarCaneBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SugarCaneBlockBehavior.java index c8f0dfc67..7fe72f9f6 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SugarCaneBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SugarCaneBlockBehavior.java @@ -38,17 +38,15 @@ public class SugarCaneBlockBehavior extends BushBlockBehavior { private final boolean nearLava; private final IntegerProperty ageProperty; private final float growSpeed; - private final CustomBlock customBlock; public SugarCaneBlockBehavior(CustomBlock customBlock, List tagsCanSurviveOn, Set blocksCansSurviveOn, Set customBlocksCansSurviveOn, Property ageProperty, int maxHeight, boolean nearWater, boolean nearLava, float growSpeed) { - super(tagsCanSurviveOn, blocksCansSurviveOn, customBlocksCansSurviveOn); + super(customBlock, tagsCanSurviveOn, blocksCansSurviveOn, customBlocksCansSurviveOn); this.nearWater = nearWater; this.nearLava = nearLava; this.maxHeight = maxHeight; this.ageProperty = (IntegerProperty) ageProperty; this.growSpeed = growSpeed; - this.customBlock = customBlock; } @Override @@ -120,13 +118,13 @@ public class SugarCaneBlockBehavior extends BushBlockBehavior { if (age >= this.ageProperty.max || RandomUtils.generateRandomFloat(0, 1) < this.growSpeed) { Object abovePos = LocationUtils.above(blockPos); if (VersionHelper.isVersionNewerThan1_21_5()) { - Reflections.method$CraftEventFactory$handleBlockGrowEvent.invoke(null, level, abovePos, customBlock.defaultState().customBlockState().handle(), UpdateOption.UPDATE_ALL.flags()); + Reflections.method$CraftEventFactory$handleBlockGrowEvent.invoke(null, level, abovePos, super.customBlock.defaultState().customBlockState().handle(), UpdateOption.UPDATE_ALL.flags()); } else { - Reflections.method$CraftEventFactory$handleBlockGrowEvent.invoke(null, level, abovePos, customBlock.defaultState().customBlockState().handle()); + Reflections.method$CraftEventFactory$handleBlockGrowEvent.invoke(null, level, abovePos, super.customBlock.defaultState().customBlockState().handle()); } - Reflections.method$Level$setBlock.invoke(level, blockPos, currentState.with(this.ageProperty, this.ageProperty.min).customBlockState().handle(), UpdateOption.UPDATE_NONE.flags()); + FastNMS.INSTANCE.method$LevelWriter$setBlock(level, blockPos, currentState.with(this.ageProperty, this.ageProperty.min).customBlockState().handle(), UpdateOption.UPDATE_NONE.flags()); } else if (RandomUtils.generateRandomFloat(0, 1) < this.growSpeed) { - Reflections.method$Level$setBlock.invoke(level, blockPos, currentState.with(this.ageProperty, age + 1).customBlockState().handle(), UpdateOption.UPDATE_NONE.flags()); + FastNMS.INSTANCE.method$LevelWriter$setBlock(level, blockPos, currentState.with(this.ageProperty, age + 1).customBlockState().handle(), UpdateOption.UPDATE_NONE.flags()); } } } @@ -143,7 +141,7 @@ public class SugarCaneBlockBehavior extends BushBlockBehavior { // 如果下方是同种方块 if (!BlockStateUtils.isVanillaBlock(id)) { ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(id); - if (immutableBlockState.owner().value() == this.customBlock) { + if (immutableBlockState.owner().value() == super.customBlock) { return true; } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/WaterLoggedBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/WaterLoggedBlockBehavior.java index 401c56bc0..ae874f173 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/WaterLoggedBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/WaterLoggedBlockBehavior.java @@ -1,7 +1,6 @@ package net.momirealms.craftengine.bukkit.block.behavior; import net.momirealms.craftengine.core.block.CustomBlock; -import net.momirealms.craftengine.core.block.behavior.AbstractBlockBehavior; import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory; import net.momirealms.craftengine.core.block.properties.Property; import net.momirealms.craftengine.shared.block.BlockBehavior; @@ -9,12 +8,13 @@ import org.jetbrains.annotations.Nullable; import java.util.Map; -public class WaterLoggedBlockBehavior extends AbstractBlockBehavior { +public class WaterLoggedBlockBehavior extends BukkitBlockBehavior { public static final Factory FACTORY = new Factory(); @Nullable private final Property waterloggedProperty; - public WaterLoggedBlockBehavior(@Nullable Property waterloggedProperty) { + public WaterLoggedBlockBehavior(CustomBlock block, @Nullable Property waterloggedProperty) { + super(block); this.waterloggedProperty = waterloggedProperty; } @@ -82,7 +82,7 @@ public class WaterLoggedBlockBehavior extends AbstractBlockBehavior { @Override public BlockBehavior create(CustomBlock block, Map arguments) { Property waterlogged = (Property) block.getProperty("waterlogged"); - return new WaterLoggedBlockBehavior(waterlogged); + return new WaterLoggedBlockBehavior(block, waterlogged); } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java index 36d76dec5..668c35060 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java @@ -112,9 +112,9 @@ public class LoadedFurniture { }); } try { - this.cachedSpawnPacket = Reflections.constructor$ClientboundBundlePacket.newInstance(packets); + this.cachedSpawnPacket = FastNMS.INSTANCE.constructor$ClientboundBundlePacket(packets); if (this.minimized) { - this.cachedMinimizedSpawnPacket = Reflections.constructor$ClientboundBundlePacket.newInstance(minimizedPackets); + this.cachedMinimizedSpawnPacket = FastNMS.INSTANCE.constructor$ClientboundBundlePacket(minimizedPackets); } } catch (Exception e) { CraftEngine.instance().logger().warn("Failed to init spawn packets for furniture " + id, e); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BlockItemBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BlockItemBehavior.java index e19d88049..511a3845b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BlockItemBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BlockItemBehavior.java @@ -150,7 +150,7 @@ public class BlockItemBehavior extends ItemBehavior { Object blockState = state.customBlockState().handle(); Object blockPos = LocationUtils.toBlockPos(context.getClickedPos()); Object voxelShape = Reflections.method$CollisionContext$of.invoke(null, player); - Object world = Reflections.field$CraftWorld$ServerLevel.get(context.getLevel().platformWorld()); + Object world = FastNMS.INSTANCE.field$CraftWorld$ServerLevel((World) context.getLevel().platformWorld()); boolean defaultReturn = ((!this.checkStatePlacement() || (boolean) Reflections.method$BlockStateBase$canSurvive.invoke(blockState, world, blockPos)) && (boolean) Reflections.method$ServerLevel$checkEntityCollision.invoke(world, blockState, player, voxelShape, blockPos, true)); Block block = FastNMS.INSTANCE.method$CraftBlock$at(world, blockPos); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java index c513dc9b1..2a2f64bc8 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java @@ -3,6 +3,7 @@ package net.momirealms.craftengine.bukkit.item.recipe; import com.destroystokyo.paper.event.inventory.PrepareResultEvent; import net.kyori.adventure.text.Component; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; +import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.injector.BukkitInjector; import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; @@ -347,7 +348,7 @@ public class RecipeEventListener implements Listener { BukkitRecipeManager.minecraftRecipeManager(), Reflections.instance$RecipeType$CAMPFIRE_COOKING, Reflections.constructor$SingleRecipeInput.newInstance(Reflections.method$CraftItemStack$asNMSCopy.invoke(null, itemStack)), - Reflections.field$CraftWorld$ServerLevel.get(event.getPlayer().getWorld()), + FastNMS.INSTANCE.field$CraftWorld$ServerLevel(event.getPlayer().getWorld()), null ); if (optionalMCRecipe.isEmpty()) { 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 608c891bc..688e8743b 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 @@ -1,9 +1,6 @@ package net.momirealms.craftengine.bukkit.plugin.command.feature; -import net.momirealms.craftengine.bukkit.nms.CollisionEntity; -import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; -import net.momirealms.craftengine.bukkit.util.Reflections; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager; import org.bukkit.Location; @@ -25,11 +22,7 @@ public class TestCommand extends BukkitCommandFeature { Player player = context.sender(); Location location = player.getLocation(); try { - Object level = Reflections.field$CraftWorld$ServerLevel.get(player.getWorld()); - Object aabb = FastNMS.INSTANCE.constructor$AABB(location.getBlockX(), location.getBlockY(), location.getBlockZ(), - location.getBlockX() + 1, location.getBlockY() + 1, location.getBlockZ() + 1); - CollisionEntity nmsEntity = FastNMS.INSTANCE.createCollisionEntity(level, aabb, location.getBlockX() + 0.5, location.getBlockY(), location.getBlockZ() + 0.5, false); - FastNMS.INSTANCE.method$LevelWriter$addFreshEntity(level, nmsEntity); + } catch (Exception e) { e.printStackTrace(); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java index a2656ed50..5be2a0711 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java @@ -174,6 +174,12 @@ public class BukkitInjector { // getShape .method(ElementMatchers.is(Reflections.method$BlockBehaviour$getShape)) .intercept(MethodDelegation.to(GetShapeInterceptor.INSTANCE)) + // mirror + .method(ElementMatchers.is(Reflections.method$BlockBehaviour$mirror)) + .intercept(MethodDelegation.to(MirrorInterceptor.INSTANCE)) + // rotate + .method(ElementMatchers.is(Reflections.method$BlockBehaviour$rotate)) + .intercept(MethodDelegation.to(RotateInterceptor.INSTANCE)) // tick .method(ElementMatchers.is(Reflections.method$BlockBehaviour$tick)) .intercept(MethodDelegation.to(TickInterceptor.INSTANCE)) @@ -711,8 +717,8 @@ public class BukkitInjector { int id = (int) Reflections.field$Direction$data3d.get(direction); // Y axis if (id == 0 || id == 1) { - Object chunkSource = Reflections.field$ServerLevel$chunkSource.get(serverLevel); - Reflections.method$ServerChunkCache$blockChanged.invoke(chunkSource, blockPos); + Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(serverLevel); + FastNMS.INSTANCE.method$ServerChunkCache$blockChanged(chunkSource, blockPos); if (id == 1) { NoteBlockChainUpdateUtils.noteBlockChainUpdate(serverLevel, chunkSource, Reflections.instance$Direction$DOWN, blockPos, 0); } else { @@ -736,6 +742,36 @@ public class BukkitInjector { } } + public static class MirrorInterceptor { + public static final MirrorInterceptor INSTANCE = new MirrorInterceptor(); + + @RuntimeType + public Object intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable superMethod) throws Exception { + ObjectHolder holder = ((BehaviorHolder) thisObj).getBehaviorHolder(); + try { + return holder.value().mirror(thisObj, args, superMethod); + } catch (Exception e) { + CraftEngine.instance().logger().severe("Failed to run mirror", e); + return superMethod.call(); + } + } + } + + public static class RotateInterceptor { + public static final RotateInterceptor INSTANCE = new RotateInterceptor(); + + @RuntimeType + public Object intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable superMethod) throws Exception { + ObjectHolder holder = ((BehaviorHolder) thisObj).getBehaviorHolder(); + try { + return holder.value().rotate(thisObj, args, superMethod); + } catch (Exception e) { + CraftEngine.instance().logger().severe("Failed to run rotate", e); + return superMethod.call(); + } + } + } + public static class RandomTickInterceptor { public static final RandomTickInterceptor INSTANCE = new RandomTickInterceptor(); 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 c87622e84..d55ca3054 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 @@ -92,31 +92,19 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes } this.registerConsumers(); this.packetsConsumer = ((serverPlayer, packets) -> { - try { - Object bundle = Reflections.constructor$ClientboundBundlePacket.newInstance(packets); - Reflections.method$ServerGamePacketListenerImpl$sendPacket.invoke( - Reflections.field$ServerPlayer$connection.get(serverPlayer), bundle); - } catch (ReflectiveOperationException e) { - plugin.logger().warn("Failed to create bundle packet", e); - } + Object bundle = FastNMS.INSTANCE.constructor$ClientboundBundlePacket(packets); + FastNMS.INSTANCE.sendPacket(serverPlayer, bundle); }); - this.delayedPacketConsumer = (serverPlayer, packet) -> { - try { - Reflections.method$ServerGamePacketListenerImpl$sendPacket.invoke( - Reflections.field$ServerPlayer$connection.get(serverPlayer), packet); - } catch (ReflectiveOperationException e) { - plugin.logger().warn("Failed to invoke send packet", e); - } - }; + this.delayedPacketConsumer = FastNMS.INSTANCE::sendPacket; this.immediatePacketConsumer = (serverPlayer, packet) -> { try { - Reflections.method$Connection$sendPacketImmediate.invoke(Reflections.field$ServerCommonPacketListenerImpl$connection.get(Reflections.field$ServerPlayer$connection.get(serverPlayer)), packet, null, true); + Reflections.method$Connection$sendPacketImmediate.invoke(FastNMS.INSTANCE.field$Player$connection$connection(serverPlayer), packet, null, true); } catch (ReflectiveOperationException e) { plugin.logger().warn("Failed to invoke send packet", e); } }; this.active = true; - this.hasModelEngine = Bukkit.getPluginManager().getPlugin("ModelEngine") != null; + hasModelEngine = Bukkit.getPluginManager().getPlugin("ModelEngine") != null; instance = this; } @@ -258,17 +246,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes } public Channel getChannel(Player player) { - try { - return (Channel) Reflections.field$Channel.get( - Reflections.field$NetworkManager.get( - Reflections.field$ServerPlayer$connection.get( - FastNMS.INSTANCE.method$CraftPlayer$getHandle(player) - ) - ) - ); - } catch (ReflectiveOperationException e) { - throw new RuntimeException(e); - } + return (Channel) FastNMS.INSTANCE.field$Player$connection$connection$channel(FastNMS.INSTANCE.method$CraftPlayer$getHandle(player)); } public void sendPacket(@NotNull Player player, @NotNull Object packet) { 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 007854ac8..45121029f 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 @@ -291,7 +291,7 @@ public class PacketConsumers { private static void handlePlayerActionPacketOnMainThread(BukkitServerPlayer player, World world, BlockPos pos, Object packet) throws Exception { Object action = Reflections.field$ServerboundPlayerActionPacket$action.get(packet); if (action == Reflections.instance$ServerboundPlayerActionPacket$Action$START_DESTROY_BLOCK) { - Object serverLevel = Reflections.field$CraftWorld$ServerLevel.get(world); + Object serverLevel = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(world); Object blockState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(serverLevel, LocationUtils.toBlockPos(pos)); int stateId = BlockStateUtils.blockStateToId(blockState); // not a custom block @@ -546,7 +546,7 @@ public class PacketConsumers { }; private static void handlePickItemFromBlockPacketOnMainThread(Player player, Object pos) throws Exception { - Object serverLevel = Reflections.field$CraftWorld$ServerLevel.get(player.getWorld()); + Object serverLevel = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(player.getWorld()); Object blockState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(serverLevel, pos); ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState)); if (state == null) return; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/DirectionUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/DirectionUtils.java index 1f587764e..1a2e8be93 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/DirectionUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/DirectionUtils.java @@ -40,4 +40,13 @@ public class DirectionUtils { case EAST -> Reflections.instance$Direction$EAST; }; } + + public static Direction fromNMSDirection(Object direction) { + try { + int index = (int) Reflections.method$Direction$ordinal.invoke(direction); + return Direction.values()[index]; + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/LightUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/LightUtils.java index 27bb4e598..7d84c1a83 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/LightUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/LightUtils.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.bukkit.util; +import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.core.plugin.CraftEngine; import org.bukkit.World; @@ -11,30 +12,25 @@ public class LightUtils { private LightUtils() {} - @SuppressWarnings("unchecked") public static void updateChunkLight(World world, Map sectionPosSet) { try { - Object serverLevel = Reflections.field$CraftWorld$ServerLevel.get(world); - Object chunkSource = Reflections.field$ServerLevel$chunkSource.get(serverLevel); + Object serverLevel = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(world); + Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(serverLevel); for (Map.Entry entry : sectionPosSet.entrySet()) { long chunkKey = entry.getKey(); - Object chunkHolder = Reflections.method$ServerChunkCache$getVisibleChunkIfPresent.invoke(chunkSource, chunkKey); + Object chunkHolder = FastNMS.INSTANCE.method$ServerChunkCache$getVisibleChunkIfPresent(chunkSource, chunkKey); if (chunkHolder == null) continue; - List players; - if (Reflections.method$ChunkHolder$getPlayers != null) { - players = (List) Reflections.method$ChunkHolder$getPlayers.invoke(chunkHolder, false); - } else { - Object chunkHolder$PlayerProvider = Reflections.field$ChunkHolder$playerProvider.get(chunkHolder); - players = (List) Reflections.method$ChunkHolder$PlayerProvider$getPlayers.invoke(chunkHolder$PlayerProvider, false); - } + List players = FastNMS.INSTANCE.method$ChunkHolder$getPlayers(chunkHolder); if (players.isEmpty()) continue; Object lightEngine = Reflections.field$ChunkHolder$lightEngine.get(chunkHolder); BitSet blockChangedLightSectionFilter = (BitSet) Reflections.field$ChunkHolder$blockChangedLightSectionFilter.get(chunkHolder); blockChangedLightSectionFilter.or(entry.getValue()); BitSet skyChangedLightSectionFilter = (BitSet) Reflections.field$ChunkHolder$skyChangedLightSectionFilter.get(chunkHolder); - Object chunkPos = Reflections.constructor$ChunkPos.newInstance((int) chunkKey, (int) (chunkKey >> 32)); - Object lightPacket = Reflections.constructor$ClientboundLightUpdatePacket.newInstance(chunkPos, lightEngine, skyChangedLightSectionFilter, blockChangedLightSectionFilter); - Reflections.method$ChunkHolder$broadcast.invoke(chunkHolder, players, lightPacket); + Object chunkPos = FastNMS.INSTANCE.constructor$ChunkPos((int) chunkKey, (int) (chunkKey >> 32)); + Object lightPacket = FastNMS.INSTANCE.constructor$ClientboundLightUpdatePacket(chunkPos, lightEngine, skyChangedLightSectionFilter, blockChangedLightSectionFilter); + for (Object player : players) { + FastNMS.INSTANCE.sendPacket(player, lightPacket); + } blockChangedLightSectionFilter.clear(); skyChangedLightSectionFilter.clear(); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/MirrorUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/MirrorUtils.java new file mode 100644 index 000000000..1aae07bd1 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/MirrorUtils.java @@ -0,0 +1,31 @@ +package net.momirealms.craftengine.bukkit.util; + +import net.momirealms.craftengine.core.util.Mirror; + +public class MirrorUtils { + + private MirrorUtils() {} + + public static Mirror fromNMSMirror(Object mirror) { + try { + int index = (int) Reflections.method$Mirror$ordinal.invoke(mirror); + return Mirror.values()[index]; + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + public static Object toNMSMirror(Mirror mirror) { + switch (mirror) { + case FRONT_BACK -> { + return Reflections.instance$Mirror$FRONT_BACK; + } + case LEFT_RIGHT -> { + return Reflections.instance$Mirror$LEFT_RIGHT; + } + default -> { + return Reflections.instance$Mirror$NONE; + } + } + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/NoteBlockChainUpdateUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/NoteBlockChainUpdateUtils.java index 5b4f28f4a..5127e9916 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/NoteBlockChainUpdateUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/NoteBlockChainUpdateUtils.java @@ -12,7 +12,7 @@ public class NoteBlockChainUpdateUtils { Object relativePos = Reflections.method$BlockPos$relative.invoke(blockPos, direction); Object state = FastNMS.INSTANCE.method$BlockGetter$getBlockState(level, relativePos); if (BlockStateUtils.isClientSideNoteBlock(state)) { - Reflections.method$ServerChunkCache$blockChanged.invoke(chunkSource, relativePos); + FastNMS.INSTANCE.method$ServerChunkCache$blockChanged(chunkSource, relativePos); noteBlockChainUpdate(level, chunkSource, direction, relativePos, times+1); } } 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 860171138..615964127 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 @@ -421,9 +421,9 @@ public class Reflections { ) ); - public static final Constructor constructor$ClientboundBundlePacket = requireNonNull( - ReflectionUtils.getConstructor(clazz$ClientboundBundlePacket, Iterable.class) - ); +// public static final Constructor constructor$ClientboundBundlePacket = requireNonNull( +// ReflectionUtils.getConstructor(clazz$ClientboundBundlePacket, Iterable.class) +// ); public static final Class clazz$Packet = requireNonNull( ReflectionUtils.getClazz( @@ -494,12 +494,6 @@ public class Reflections { ) ); - public static final Field field$NetworkManager = requireNonNull( - VersionHelper.isVersionNewerThan1_20_2() ? - ReflectionUtils.getDeclaredField(clazz$ServerGamePacketListenerImpl.getSuperclass(), clazz$Connection, 0) : - ReflectionUtils.getDeclaredField(clazz$ServerGamePacketListenerImpl, clazz$Connection, 0) - ); - public static final Field field$Channel = requireNonNull( ReflectionUtils.getDeclaredField( clazz$Connection, Channel.class, 0 @@ -1053,11 +1047,12 @@ public class Reflections { ) ); - public static final Field field$CraftWorld$ServerLevel = requireNonNull( - ReflectionUtils.getDeclaredField( - clazz$CraftWorld, clazz$ServerLevel, 0 - ) - ); +// @Deprecated +// public static final Field field$CraftWorld$ServerLevel = requireNonNull( +// ReflectionUtils.getDeclaredField( +// clazz$CraftWorld, clazz$ServerLevel, 0 +// ) +// ); public static final Method method$ServerLevel$getNoiseBiome = requireNonNull( ReflectionUtils.getMethod( @@ -1806,17 +1801,18 @@ public class Reflections { ) ); - public static final Field field$ServerLevel$chunkSource = requireNonNull( - ReflectionUtils.getDeclaredField( - clazz$ServerLevel, clazz$ServerChunkCache, 0 - ) - ); + @Deprecated +// public static final Field field$ServerLevel$chunkSource = requireNonNull( +// ReflectionUtils.getDeclaredField( +// clazz$ServerLevel, clazz$ServerChunkCache, 0 +// ) +// ); - public static final Method method$ServerChunkCache$blockChanged = requireNonNull( - ReflectionUtils.getMethod( - clazz$ServerChunkCache, void.class, clazz$BlockPos - ) - ); +// public static final Method method$ServerChunkCache$blockChanged = requireNonNull( +// ReflectionUtils.getMethod( +// clazz$ServerChunkCache, void.class, clazz$BlockPos +// ) +// ); // public static final Method method$ServerChunkCache$getChunkAtIfLoadedMainThread = requireNonNull( // ReflectionUtils.getMethod( @@ -2644,6 +2640,7 @@ public class Reflections { ) ); + @Deprecated public static final Constructor constructor$ChunkPos = requireNonNull( ReflectionUtils.getConstructor( clazz$ChunkPos, int.class, int.class @@ -2695,7 +2692,7 @@ public class Reflections { ) ); - // 1.20 ~ 1.21.4 + // 1.20 ~ 1.21.4 moonrise public static final Method method$ChunkHolder$getPlayers = ReflectionUtils.getMethod( clazz$ChunkHolder, List.class, boolean.class @@ -2725,6 +2722,7 @@ public class Reflections { ) ); + @Deprecated public static final Method method$ServerChunkCache$getVisibleChunkIfPresent = requireNonNull( ReflectionUtils.getDeclaredMethod( clazz$ServerChunkCache, clazz$ChunkHolder, long.class @@ -3577,12 +3575,6 @@ public class Reflections { ) ); - public static final Method method$Level$setBlock = requireNonNull( - ReflectionUtils.getMethod( - clazz$Level, boolean.class, clazz$BlockPos, clazz$BlockState, int.class - ) - ); - public static final Method method$Block$updateFromNeighbourShapes = requireNonNull( ReflectionUtils.getStaticMethod( clazz$Block, clazz$BlockState, clazz$BlockState, clazz$LevelAccessor, clazz$BlockPos @@ -3735,6 +3727,7 @@ public class Reflections { ) ); + @Deprecated public static final Method method$LevelWriter$setBlock = requireNonNull( ReflectionUtils.getMethod( clazz$LevelWriter, boolean.class, clazz$BlockPos, clazz$BlockState, int.class @@ -5963,4 +5956,86 @@ public class Reflections { clazz$ClientboundSetEntityMotionPacket, int.class, 0 ) ); + + public static final Class clazz$Rotation = requireNonNull( + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleMCClass("world.level.block.Rotation"), + BukkitReflectionUtils.assembleMCClass("world.level.block.EnumBlockRotation") + ) + ); + + public static final Method method$Rotation$values = requireNonNull( + ReflectionUtils.getStaticMethod( + clazz$Rotation, clazz$Rotation.arrayType() + ) + ); + + public static final Object instance$Rotation$NONE; + public static final Object instance$Rotation$CLOCKWISE_90; + public static final Object instance$Rotation$CLOCKWISE_180; + public static final Object instance$Rotation$COUNTERCLOCKWISE_90; + + static { + try { + Object[] values = (Object[]) method$Rotation$values.invoke(null); + instance$Rotation$NONE = values[0]; + instance$Rotation$CLOCKWISE_90 = values[1]; + instance$Rotation$CLOCKWISE_180 = values[2]; + instance$Rotation$COUNTERCLOCKWISE_90 = values[3]; + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + public static final Method method$Rotation$ordinal = requireNonNull( + ReflectionUtils.getMethod( + clazz$Rotation, int.class, new String[]{"ordinal"} + ) + ); + + public static final Class clazz$Mirror = requireNonNull( + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleMCClass("world.level.block.Mirror"), + BukkitReflectionUtils.assembleMCClass("world.level.block.EnumBlockMirror") + ) + ); + + public static final Method method$Mirror$values = requireNonNull( + ReflectionUtils.getStaticMethod( + clazz$Mirror, clazz$Mirror.arrayType() + ) + ); + + public static final Object instance$Mirror$NONE; + public static final Object instance$Mirror$LEFT_RIGHT; + public static final Object instance$Mirror$FRONT_BACK; + + static { + try { + Object[] values = (Object[]) method$Mirror$values.invoke(null); + instance$Mirror$NONE = values[0]; + instance$Mirror$LEFT_RIGHT = values[1]; + instance$Mirror$FRONT_BACK = values[2]; + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + public static final Method method$Mirror$ordinal = requireNonNull( + ReflectionUtils.getMethod( + clazz$Mirror, int.class, new String[]{"ordinal"} + ) + ); + + public static final Method method$BlockBehaviour$rotate = requireNonNull( + ReflectionUtils.getDeclaredMethod( + clazz$BlockBehaviour, clazz$BlockState, clazz$BlockState, clazz$Rotation + ) + ); + + public static final Method method$BlockBehaviour$mirror = requireNonNull( + ReflectionUtils.getDeclaredMethod( + clazz$BlockBehaviour, clazz$BlockState, clazz$BlockState, clazz$Mirror + ) + ); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/RotationUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/RotationUtils.java new file mode 100644 index 000000000..95cd0b40c --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/RotationUtils.java @@ -0,0 +1,34 @@ +package net.momirealms.craftengine.bukkit.util; + +import net.momirealms.craftengine.core.util.Rotation; + +public class RotationUtils { + + private RotationUtils() {} + + public static Rotation fromNMSRotation(Object rotation) { + try { + int index = (int) Reflections.method$Rotation$ordinal.invoke(rotation); + return Rotation.values()[index]; + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + public static Object toNMSRotation(Rotation rotation) { + switch (rotation) { + case CLOCKWISE_90 -> { + return Reflections.instance$Rotation$CLOCKWISE_90; + } + case CLOCKWISE_180 -> { + return Reflections.instance$Rotation$CLOCKWISE_180; + } + case COUNTERCLOCKWISE_90 -> { + return Reflections.instance$Rotation$COUNTERCLOCKWISE_90; + } + default -> { + return Reflections.instance$Rotation$NONE; + } + } + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorld.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorld.java index 89192c5ac..5e6aa6235 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorld.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorld.java @@ -1,8 +1,8 @@ package net.momirealms.craftengine.bukkit.world; +import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.util.EntityUtils; import net.momirealms.craftengine.bukkit.util.ItemUtils; -import net.momirealms.craftengine.bukkit.util.Reflections; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.VersionHelper; @@ -36,7 +36,7 @@ public class BukkitWorld implements World { @Override public Object serverWorld() { try { - return Reflections.field$CraftWorld$ServerLevel.get(platformWorld()); + return FastNMS.INSTANCE.field$CraftWorld$ServerLevel(platformWorld()); } catch (Exception e) { throw new RuntimeException("Failed to get server world", e); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldBlock.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldBlock.java index c7840ffb8..c1addb16d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldBlock.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldBlock.java @@ -3,6 +3,7 @@ package net.momirealms.craftengine.bukkit.world; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.item.behavior.BlockItemBehavior; +import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.util.BlockStateUtils; import net.momirealms.craftengine.bukkit.util.LocationUtils; import net.momirealms.craftengine.bukkit.util.Reflections; @@ -51,7 +52,7 @@ public class BukkitWorldBlock implements WorldBlock { public boolean isWaterSource(BlockPlaceContext blockPlaceContext) { try { Location location = block.getLocation(); - Object serverLevel = Reflections.field$CraftWorld$ServerLevel.get(block.getWorld()); + Object serverLevel = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(block.getWorld()); Object fluidData = Reflections.method$Level$getFluidState.invoke(serverLevel, LocationUtils.toBlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ())); if (fluidData == null) return false; return (boolean) Reflections.method$FluidState$isSource.invoke(fluidData); diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/behavior/AbstractBlockBehavior.java b/core/src/main/java/net/momirealms/craftengine/core/block/behavior/AbstractBlockBehavior.java index 948700454..ae8d38e1e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/behavior/AbstractBlockBehavior.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/behavior/AbstractBlockBehavior.java @@ -1,10 +1,16 @@ package net.momirealms.craftengine.core.block.behavior; +import net.momirealms.craftengine.core.block.CustomBlock; import net.momirealms.craftengine.core.block.ImmutableBlockState; import net.momirealms.craftengine.core.item.context.BlockPlaceContext; import net.momirealms.craftengine.shared.block.BlockBehavior; public abstract class AbstractBlockBehavior extends BlockBehavior { + protected CustomBlock customBlock; + + public AbstractBlockBehavior(CustomBlock customBlock) { + this.customBlock = customBlock; + } public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) { return state; diff --git a/gradle.properties b/gradle.properties index cc5ca5e33..b7ec30623 100644 --- a/gradle.properties +++ b/gradle.properties @@ -49,7 +49,7 @@ mojang_brigadier_version=1.0.18 byte_buddy_version=1.15.11 snake_yaml_version=2.3 anti_grief_version=0.13 -nms_helper_version=0.29 +nms_helper_version=0.32 # Ignite Dependencies mixinextras_version=0.4.1 mixin_version=0.15.2+mixin.0.8.7 diff --git a/server-mod/src/main/java/net/momirealms/craftengine/mod/CraftEngineBlock.java b/server-mod/src/main/java/net/momirealms/craftengine/mod/CraftEngineBlock.java index 54effc4b0..f7d481ee7 100644 --- a/server-mod/src/main/java/net/momirealms/craftengine/mod/CraftEngineBlock.java +++ b/server-mod/src/main/java/net/momirealms/craftengine/mod/CraftEngineBlock.java @@ -10,10 +10,7 @@ import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.ScheduledTickAccess; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.BonemealableBlock; -import net.minecraft.world.level.block.Fallable; +import net.minecraft.world.level.block.*; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; @@ -68,10 +65,30 @@ public class CraftEngineBlock } } + @Override + protected @NotNull BlockState rotate(@NotNull BlockState state, @NotNull Rotation rotation) { + try { + return (BlockState) this.behaviorHolder.value().rotate(this, new Object[]{state, rotation}, () -> super.rotate(state, rotation)); + } catch (Exception e) { + e.printStackTrace(); + return super.rotate(state, rotation); + } + } + + @Override + protected @NotNull BlockState mirror(@NotNull BlockState state, @NotNull Mirror mirror) { + try { + return (BlockState) this.behaviorHolder.value().mirror(this, new Object[]{state, mirror}, () -> super.mirror(state, mirror)); + } catch (Exception e) { + e.printStackTrace(); + return super.mirror(state, mirror); + } + } + @Override protected void tick(@NotNull BlockState state, @NotNull ServerLevel level, @NotNull BlockPos pos, @NotNull RandomSource random) { try { - behaviorHolder.value().tick(this, new Object[]{state, level, pos, random}, () -> { + this.behaviorHolder.value().tick(this, new Object[]{state, level, pos, random}, () -> { super.tick(state, level, pos, random); return null; }); diff --git a/shared/src/main/java/net/momirealms/craftengine/shared/block/BlockBehavior.java b/shared/src/main/java/net/momirealms/craftengine/shared/block/BlockBehavior.java index 957e207d2..67c22fbd8 100644 --- a/shared/src/main/java/net/momirealms/craftengine/shared/block/BlockBehavior.java +++ b/shared/src/main/java/net/momirealms/craftengine/shared/block/BlockBehavior.java @@ -4,6 +4,14 @@ import java.util.concurrent.Callable; public abstract class BlockBehavior { + public Object rotate(Object thisBlock, Object[] args, Callable superMethod) throws Exception { + return superMethod.call(); + } + + public Object mirror(Object thisBlock, Object[] args, Callable superMethod) throws Exception { + return superMethod.call(); + } + public Object updateShape(Object thisBlock, Object[] args, Callable superMethod) throws Exception { return superMethod.call(); } From c83a06f5bacc7b9c813437462773677d21f07d89 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Wed, 2 Apr 2025 20:28:44 +0800 Subject: [PATCH 11/19] improve API speed --- .../bukkit/api/CraftEngineBlocks.java | 25 ++++++++----------- gradle.properties | 2 +- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java index 79a27fcc7..f34eb8935 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java @@ -107,21 +107,16 @@ public final class CraftEngineBlocks { @NotNull UpdateOption option, boolean playSound) { boolean success; - try { - Object worldServer = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(location.getWorld()); - Object blockPos = FastNMS.INSTANCE.constructor$BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()); - Object blockState = block.customBlockState().handle(); - Object oldBlockState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(worldServer, blockPos); - success = FastNMS.INSTANCE.method$LevelWriter$setBlock(worldServer, blockPos, blockState, option.flags()); - if (success) { - Reflections.method$BlockStateBase$onPlace.invoke(blockState, worldServer, blockPos, oldBlockState, true); - if (playSound) { - location.getWorld().playSound(location, block.sounds().placeSound().toString(), SoundCategory.BLOCKS, block.sounds().placeSound().volume(), block.sounds().placeSound().pitch()); - } + Object worldServer = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(location.getWorld()); + Object blockPos = FastNMS.INSTANCE.constructor$BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()); + Object blockState = block.customBlockState().handle(); + Object oldBlockState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(worldServer, blockPos); + success = FastNMS.INSTANCE.method$LevelWriter$setBlock(worldServer, blockPos, blockState, option.flags()); + if (success) { + FastNMS.INSTANCE.method$BlockStateBase$onPlace(blockState, worldServer, blockPos, oldBlockState, false); + if (playSound) { + location.getWorld().playSound(location, block.sounds().placeSound().toString(), SoundCategory.BLOCKS, block.sounds().placeSound().volume(), block.sounds().placeSound().pitch()); } - } catch (ReflectiveOperationException e) { - CraftEngine.instance().logger().warn("Failed to set nms block", e); - return false; } return success; } @@ -189,7 +184,7 @@ public final class CraftEngineBlocks { world.playBlockSound(vec3d, state.sounds().breakSound()); } if (sendParticles) { - // TODO Particles + // TODO Particles. needs world event //ParticleUtils.addBlockBreakParticles(block.getWorld(), LocationUtils.toBlockPos(location), state.customBlockState().handle()); } block.setType(Material.AIR, applyPhysics); diff --git a/gradle.properties b/gradle.properties index b7ec30623..295ac58ef 100644 --- a/gradle.properties +++ b/gradle.properties @@ -49,7 +49,7 @@ mojang_brigadier_version=1.0.18 byte_buddy_version=1.15.11 snake_yaml_version=2.3 anti_grief_version=0.13 -nms_helper_version=0.32 +nms_helper_version=0.33 # Ignite Dependencies mixinextras_version=0.4.1 mixin_version=0.15.2+mixin.0.8.7 From 8b49039894af8cb2513426540e407fe960175cd4 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Wed, 2 Apr 2025 21:41:04 +0800 Subject: [PATCH 12/19] fix facing mirror --- .../bukkit/block/behavior/BukkitBlockBehavior.java | 8 ++++---- .../craftengine/bukkit/util/Reflections.java | 12 ++++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BukkitBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BukkitBlockBehavior.java index 93ad23eb6..86b481813 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BukkitBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BukkitBlockBehavior.java @@ -61,14 +61,14 @@ public class BukkitBlockBehavior extends AbstractBlockBehavior { } }); HARD_CODED_PROPERTY_DATA.put("facing_clockwise", (behavior, property) -> { - if (property.valueClass() == Direction.class) { + if (property.valueClass() == HorizontalDirection.class) { @SuppressWarnings("unchecked") - Property directionProperty = (Property) property; + Property directionProperty = (Property) property; behavior.rotateFunction = (thisBlock, blockState, rotation) -> - blockState.with(directionProperty, rotation.rotate(blockState.get(directionProperty))) + blockState.with(directionProperty, rotation.rotate(blockState.get(directionProperty).toDirection()).toHorizontalDirection()) .customBlockState().handle(); behavior.mirrorFunction = (thisBlock, blockState, mirror) -> { - Rotation rotation = mirror.getRotation(blockState.get(directionProperty)); + Rotation rotation = mirror.getRotation(blockState.get(directionProperty).toDirection()); return behavior.rotateFunction.rotate(thisBlock, blockState, rotation); }; } 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 615964127..6932a75b8 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 @@ -6038,4 +6038,16 @@ public class Reflections { clazz$BlockBehaviour, clazz$BlockState, clazz$BlockState, clazz$Mirror ) ); + + public static final Method method$BlockStateBase$rotate = requireNonNull( + ReflectionUtils.getMethod( + clazz$BlockStateBase, clazz$BlockState, clazz$Rotation + ) + ); + + public static final Method method$BlockStateBase$mirror = requireNonNull( + ReflectionUtils.getMethod( + clazz$BlockStateBase, clazz$BlockState, clazz$Mirror + ) + ); } From 13ca7d018c567de4987a35f9fcf554b306a00687 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Wed, 2 Apr 2025 22:04:12 +0800 Subject: [PATCH 13/19] fix memory leak & improve speed --- .../bukkit/api/CraftEngineFurniture.java | 10 ++--- .../furniture/BukkitFurnitureManager.java | 38 ++++++++----------- .../plugin/network/PacketConsumers.java | 14 ++----- .../entity/furniture/FurnitureManager.java | 2 +- 4 files changed, 26 insertions(+), 38 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineFurniture.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineFurniture.java index 04f57f418..436f677b3 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineFurniture.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineFurniture.java @@ -139,7 +139,7 @@ public class CraftEngineFurniture { */ @Nullable public static LoadedFurniture getLoadedFurnitureByBaseEntity(@NotNull Entity baseEntity) { - return BukkitFurnitureManager.instance().getLoadedFurnitureByBaseEntityId(baseEntity.getEntityId()); + return BukkitFurnitureManager.instance().getLoadedFurnitureByRealEntityId(baseEntity.getEntityId()); } /** @@ -152,7 +152,7 @@ public class CraftEngineFurniture { public static LoadedFurniture getLoadedFurnitureBySeat(@NotNull Entity seat) { Integer baseEntityId = seat.getPersistentDataContainer().get(BukkitFurnitureManager.FURNITURE_SEAT_BASE_ENTITY_KEY, PersistentDataType.INTEGER); if (baseEntityId == null) return null; - return BukkitFurnitureManager.instance().getLoadedFurnitureByBaseEntityId(baseEntityId); + return BukkitFurnitureManager.instance().getLoadedFurnitureByRealEntityId(baseEntityId); } /** @@ -163,7 +163,7 @@ public class CraftEngineFurniture { */ public static boolean remove(@NotNull Entity furniture) { if (!isFurniture(furniture)) return false; - LoadedFurniture loadedFurniture = BukkitFurnitureManager.instance().getLoadedFurnitureByBaseEntityId(furniture.getEntityId()); + LoadedFurniture loadedFurniture = BukkitFurnitureManager.instance().getLoadedFurnitureByRealEntityId(furniture.getEntityId()); if (loadedFurniture == null) return false; loadedFurniture.destroy(); return true; @@ -181,7 +181,7 @@ public class CraftEngineFurniture { boolean dropLoot, boolean playSound) { if (!isFurniture(furniture)) return false; - LoadedFurniture loadedFurniture = BukkitFurnitureManager.instance().getLoadedFurnitureByBaseEntityId(furniture.getEntityId()); + LoadedFurniture loadedFurniture = BukkitFurnitureManager.instance().getLoadedFurnitureByRealEntityId(furniture.getEntityId()); if (loadedFurniture == null) return false; remove(loadedFurniture, (net.momirealms.craftengine.core.entity.player.Player) null, dropLoot, playSound); return true; @@ -201,7 +201,7 @@ public class CraftEngineFurniture { boolean dropLoot, boolean playSound) { if (!isFurniture(furniture)) return false; - LoadedFurniture loadedFurniture = BukkitFurnitureManager.instance().getLoadedFurnitureByBaseEntityId(furniture.getEntityId()); + LoadedFurniture loadedFurniture = BukkitFurnitureManager.instance().getLoadedFurnitureByRealEntityId(furniture.getEntityId()); if (loadedFurniture == null) return false; remove(loadedFurniture, player, dropLoot, playSound); return true; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java index d2d48310d..5f3e8a199 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java @@ -41,9 +41,8 @@ public class BukkitFurnitureManager implements FurnitureManager { private final Map byId = new HashMap<>(); - private final Map furnitureByBaseEntityId = new ConcurrentHashMap<>(256, 0.5f); + private final Map furnitureByRealEntityId = new ConcurrentHashMap<>(256, 0.5f); private final Map furnitureByEntityId = new ConcurrentHashMap<>(512, 0.5f); - private final Map furnitureByCollisionEntitiesId = new ConcurrentHashMap<>(256, 0.5f); // Event listeners private final Listener dismountListener; private final FurnitureEventListener furnitureEventListener; @@ -78,7 +77,7 @@ public class BukkitFurnitureManager implements FurnitureManager { SoundData data = furniture.settings().sounds().placeSound(); location.getWorld().playSound(location, data.id().toString(), SoundCategory.BLOCKS, data.volume(), data.pitch()); } - return getLoadedFurnitureByBaseEntityId(furnitureEntity.getEntityId()); + return getLoadedFurnitureByRealEntityId(furnitureEntity.getEntityId()); } @Override @@ -258,13 +257,13 @@ public class BukkitFurnitureManager implements FurnitureManager { } @Override - public boolean isFurnitureBaseEntity(int entityId) { - return this.furnitureByBaseEntityId.containsKey(entityId); + public boolean isFurnitureRealEntity(int entityId) { + return this.furnitureByRealEntityId.containsKey(entityId); } @Nullable - public LoadedFurniture getLoadedFurnitureByBaseEntityId(int entityId) { - return this.furnitureByBaseEntityId.get(entityId); + public LoadedFurniture getLoadedFurnitureByRealEntityId(int entityId) { + return this.furnitureByRealEntityId.get(entityId); } @Nullable @@ -272,23 +271,18 @@ public class BukkitFurnitureManager implements FurnitureManager { return this.furnitureByEntityId.get(entityId); } - @Nullable - public LoadedFurniture getLoadedFurnitureByCollisionEntityId(int entityId) { - return this.furnitureByCollisionEntitiesId.get(entityId); - } - - public boolean isFurnitureCollisionEntity(int entityId) { - return this.furnitureByCollisionEntitiesId.containsKey(entityId); - } - protected void handleBaseFurnitureUnload(Entity entity) { int id = entity.getEntityId(); - LoadedFurniture furniture = this.furnitureByBaseEntityId.remove(id); + LoadedFurniture furniture = this.furnitureByRealEntityId.remove(id); if (furniture != null) { furniture.destroySeats(); for (int sub : furniture.entityIds()) { this.furnitureByEntityId.remove(sub); } + for (CollisionEntity collision : furniture.collisionEntities()) { + this.furnitureByRealEntityId.remove(FastNMS.INSTANCE.method$Entity$getId(collision)); + collision.destroy(); + } } } @@ -301,7 +295,7 @@ public class BukkitFurnitureManager implements FurnitureManager { Optional optionalFurniture = getFurniture(key); if (optionalFurniture.isEmpty()) return; CustomFurniture customFurniture = optionalFurniture.get(); - LoadedFurniture previous = this.furnitureByBaseEntityId.get(display.getEntityId()); + LoadedFurniture previous = this.furnitureByRealEntityId.get(display.getEntityId()); if (previous != null) return; Location location = entity.getLocation(); if (FastNMS.INSTANCE.isPreventingStatusUpdates(location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4)) { @@ -323,7 +317,7 @@ public class BukkitFurnitureManager implements FurnitureManager { Optional optionalFurniture = getFurniture(key); if (optionalFurniture.isPresent()) { CustomFurniture customFurniture = optionalFurniture.get(); - LoadedFurniture previous = this.furnitureByBaseEntityId.get(display.getEntityId()); + LoadedFurniture previous = this.furnitureByRealEntityId.get(display.getEntityId()); if (previous != null) return; addNewFurniture(display, customFurniture, getAnchorType(entity, customFurniture)); return; @@ -355,13 +349,13 @@ public class BukkitFurnitureManager implements FurnitureManager { private synchronized LoadedFurniture addNewFurniture(ItemDisplay display, CustomFurniture furniture, AnchorType anchorType) { LoadedFurniture loadedFurniture = new LoadedFurniture(display, furniture, anchorType); - this.furnitureByBaseEntityId.put(loadedFurniture.baseEntityId(), loadedFurniture); + this.furnitureByRealEntityId.put(loadedFurniture.baseEntityId(), loadedFurniture); for (int entityId : loadedFurniture.entityIds()) { this.furnitureByEntityId.put(entityId, loadedFurniture); } for (CollisionEntity collisionEntity : loadedFurniture.collisionEntities()) { int collisionEntityId = FastNMS.INSTANCE.method$Entity$getId(collisionEntity); - this.furnitureByCollisionEntitiesId.put(collisionEntityId, loadedFurniture); + this.furnitureByRealEntityId.put(collisionEntityId, loadedFurniture); } loadedFurniture.initializeColliders(); return loadedFurniture; @@ -377,7 +371,7 @@ public class BukkitFurnitureManager implements FurnitureManager { Integer baseFurniture = vehicle.getPersistentDataContainer().get(FURNITURE_SEAT_BASE_ENTITY_KEY, PersistentDataType.INTEGER); if (baseFurniture == null) return; vehicle.remove(); - LoadedFurniture furniture = getLoadedFurnitureByBaseEntityId(baseFurniture); + LoadedFurniture furniture = getLoadedFurnitureByRealEntityId(baseFurniture); if (furniture == null) { return; } 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 45121029f..424b361e6 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 @@ -618,7 +618,7 @@ public class PacketConsumers { } else if (entityType == Reflections.instance$EntityType$ITEM_DISPLAY) { // Furniture int entityId = (int) Reflections.field$ClientboundAddEntityPacket$entityId.get(packet); - LoadedFurniture furniture = BukkitFurnitureManager.instance().getLoadedFurnitureByBaseEntityId(entityId); + LoadedFurniture furniture = BukkitFurnitureManager.instance().getLoadedFurnitureByRealEntityId(entityId); if (furniture != null) { user.furnitureView().computeIfAbsent(furniture.baseEntityId(), k -> new ArrayList<>()).addAll(furniture.fakeEntityIds()); user.sendPacket(furniture.spawnPacket((Player) user.platformPlayer()), false); @@ -629,7 +629,7 @@ public class PacketConsumers { } else if (entityType == Reflections.instance$EntityType$SHULKER) { // Cancel collider entity packet int entityId = (int) Reflections.field$ClientboundAddEntityPacket$entityId.get(packet); - LoadedFurniture furniture = BukkitFurnitureManager.instance().getLoadedFurnitureByCollisionEntityId(entityId); + LoadedFurniture furniture = BukkitFurnitureManager.instance().getLoadedFurnitureByRealEntityId(entityId); if (furniture != null) { event.setCancelled(true); } @@ -642,10 +642,7 @@ public class PacketConsumers { public static final TriConsumer SYNC_ENTITY_POSITION = (user, event, packet) -> { try { int entityId = (int) Reflections.field$ClientboundEntityPositionSyncPacket$id.get(packet); - if (BukkitFurnitureManager.instance().isFurnitureBaseEntity(entityId)) { - event.setCancelled(true); - } - if (BukkitFurnitureManager.instance().isFurnitureCollisionEntity(entityId)) { + if (BukkitFurnitureManager.instance().isFurnitureRealEntity(entityId)) { event.setCancelled(true); } } catch (Exception e) { @@ -656,10 +653,7 @@ public class PacketConsumers { public static final TriConsumer MOVE_ENTITY = (user, event, packet) -> { try { int entityId = (int) Reflections.field$ClientboundMoveEntityPacket$entityId.get(packet); - if (BukkitFurnitureManager.instance().isFurnitureBaseEntity(entityId)) { - event.setCancelled(true); - } - if (BukkitFurnitureManager.instance().isFurnitureCollisionEntity(entityId)) { + if (BukkitFurnitureManager.instance().isFurnitureRealEntity(entityId)) { event.setCancelled(true); } } catch (Exception e) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/FurnitureManager.java b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/FurnitureManager.java index 100a41b5c..965337964 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/FurnitureManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/FurnitureManager.java @@ -33,5 +33,5 @@ public interface FurnitureManager extends Reloadable, ConfigSectionParser { Optional getFurniture(Key id); - boolean isFurnitureBaseEntity(int entityId); + boolean isFurnitureRealEntity(int entityId); } From 606dff9a43093d0825cf53e9efd6a30a37a15d5c Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Wed, 2 Apr 2025 22:07:34 +0800 Subject: [PATCH 14/19] add chunk status check --- .../bukkit/entity/furniture/BukkitFurnitureManager.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java index 5f3e8a199..c499b31c8 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java @@ -275,13 +275,17 @@ public class BukkitFurnitureManager implements FurnitureManager { int id = entity.getEntityId(); LoadedFurniture furniture = this.furnitureByRealEntityId.remove(id); if (furniture != null) { - furniture.destroySeats(); + Location location = entity.getLocation(); + boolean isPreventing = FastNMS.INSTANCE.isPreventingStatusUpdates(location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4); + if (!isPreventing) { + furniture.destroySeats(); + } for (int sub : furniture.entityIds()) { this.furnitureByEntityId.remove(sub); } for (CollisionEntity collision : furniture.collisionEntities()) { this.furnitureByRealEntityId.remove(FastNMS.INSTANCE.method$Entity$getId(collision)); - collision.destroy(); + if (!isPreventing) collision.destroy(); } } } From 935b7e48779239d89403141a55b4acaa08ce1674 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Wed, 2 Apr 2025 23:02:44 +0800 Subject: [PATCH 15/19] fix particles & sounds --- .../craftengine/bukkit/api/CraftEngineBlocks.java | 4 ++-- .../bukkit/block/behavior/BushBlockBehavior.java | 5 ++++- .../bukkit/block/behavior/SugarCaneBlockBehavior.java | 6 ++++-- gradle.properties | 2 +- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java index f34eb8935..3618b8d43 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java @@ -5,6 +5,7 @@ import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; import net.momirealms.craftengine.bukkit.util.BlockStateUtils; +import net.momirealms.craftengine.bukkit.util.LocationUtils; import net.momirealms.craftengine.bukkit.util.Reflections; import net.momirealms.craftengine.bukkit.world.BukkitWorld; import net.momirealms.craftengine.core.block.CustomBlock; @@ -184,8 +185,7 @@ public final class CraftEngineBlocks { world.playBlockSound(vec3d, state.sounds().breakSound()); } if (sendParticles) { - // TODO Particles. needs world event - //ParticleUtils.addBlockBreakParticles(block.getWorld(), LocationUtils.toBlockPos(location), state.customBlockState().handle()); + FastNMS.INSTANCE.method$Level$levelEvent(world.serverWorld(), 2001, LocationUtils.toBlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), state.customBlockState().registryId()); } block.setType(Material.AIR, applyPhysics); return true; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java index 7c42b3ad8..77a537757 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java @@ -63,7 +63,8 @@ public class BushBlockBehavior extends BukkitBlockBehavior { blockPos = args[4]; } if (!canSurvive(thisBlock, state, level, blockPos)) { - ImmutableBlockState previousState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(state)); + int stateId = BlockStateUtils.blockStateToId(state); + ImmutableBlockState previousState = BukkitBlockManager.instance().getImmutableBlockState(stateId); if (previousState != null && !previousState.isEmpty()) { ContextHolder.Builder builder = ContextHolder.builder(); BlockPos pos = LocationUtils.fromBlockPos(blockPos); @@ -74,6 +75,8 @@ public class BushBlockBehavior extends BukkitBlockBehavior { for (Item item : previousState.getDrops(builder, world)) { world.dropItemNaturally(vec3d, item); } + world.playBlockSound(vec3d, previousState.sounds().breakSound()); + FastNMS.INSTANCE.method$Level$levelEvent(level, 2001, blockPos, stateId); } return Reflections.method$Block$defaultBlockState.invoke(Reflections.instance$Blocks$AIR); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SugarCaneBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SugarCaneBlockBehavior.java index 7fe72f9f6..c11a5d511 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SugarCaneBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SugarCaneBlockBehavior.java @@ -55,19 +55,21 @@ public class SugarCaneBlockBehavior extends BushBlockBehavior { Object level = args[1]; Object blockPos = args[2]; if (!canSurvive(thisBlock, blockState, level, blockPos)) { - ImmutableBlockState currentState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState)); + int stateId = BlockStateUtils.blockStateToId(blockState); + ImmutableBlockState currentState = BukkitBlockManager.instance().getImmutableBlockState(stateId); if (currentState != null && !currentState.isEmpty()) { // break the sugar cane Reflections.method$Level$removeBlock.invoke(level, blockPos, false); Vec3d vec3d = Vec3d.atCenterOf(LocationUtils.fromBlockPos(blockPos)); net.momirealms.craftengine.core.world.World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level)); - // TODO client side particles? ContextHolder.Builder builder = ContextHolder.builder() .withParameter(LootParameters.LOCATION, vec3d) .withParameter(LootParameters.WORLD, world); for (Item item : currentState.getDrops(builder, world)) { world.dropItemNaturally(vec3d, item); } + world.playBlockSound(vec3d, currentState.sounds().breakSound()); + FastNMS.INSTANCE.method$Level$levelEvent(level, 2001, blockPos, stateId); } } } diff --git a/gradle.properties b/gradle.properties index 295ac58ef..4c86a43c1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -49,7 +49,7 @@ mojang_brigadier_version=1.0.18 byte_buddy_version=1.15.11 snake_yaml_version=2.3 anti_grief_version=0.13 -nms_helper_version=0.33 +nms_helper_version=0.34 # Ignite Dependencies mixinextras_version=0.4.1 mixin_version=0.15.2+mixin.0.8.7 From 92fe5c9b3d54663a22279f6a75e0220d9c9ba256 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Wed, 2 Apr 2025 23:18:36 +0800 Subject: [PATCH 16/19] improve crop block --- .../default/configuration/plants.yml | 2 + .../block/behavior/CropBlockBehavior.java | 56 ++++++++++++++++--- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/bukkit/loader/src/main/resources/resources/default/configuration/plants.yml b/bukkit/loader/src/main/resources/resources/default/configuration/plants.yml index 6cb154363..22f13a2cc 100644 --- a/bukkit/loader/src/main/resources/resources/default/configuration/plants.yml +++ b/bukkit/loader/src/main/resources/resources/default/configuration/plants.yml @@ -193,6 +193,8 @@ blocks: type: crop_block grow-speed: 0.25 light-requirement: 9 + is-bone-meal-target: true + bone-meal-age-bonus: 1 bottom-blocks: - minecraft:end_stone loot: diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/CropBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/CropBlockBehavior.java index a8b8881fd..cb2651ba5 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/CropBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/CropBlockBehavior.java @@ -5,36 +5,51 @@ import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.util.BlockStateUtils; import net.momirealms.craftengine.bukkit.util.ParticleUtils; import net.momirealms.craftengine.bukkit.util.Reflections; +import net.momirealms.craftengine.bukkit.world.BukkitWorld; import net.momirealms.craftengine.core.block.CustomBlock; import net.momirealms.craftengine.core.block.ImmutableBlockState; import net.momirealms.craftengine.core.block.UpdateOption; import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory; import net.momirealms.craftengine.core.block.properties.IntegerProperty; import net.momirealms.craftengine.core.block.properties.Property; +import net.momirealms.craftengine.core.loot.LootContext; +import net.momirealms.craftengine.core.loot.parameter.LootParameters; import net.momirealms.craftengine.core.util.MiscUtils; import net.momirealms.craftengine.core.util.RandomUtils; import net.momirealms.craftengine.core.util.Tuple; +import net.momirealms.craftengine.core.loot.number.NumberProvider; +import net.momirealms.craftengine.core.loot.number.NumberProviders; +import net.momirealms.craftengine.core.util.context.ContextHolder; +import net.momirealms.craftengine.core.util.context.ContextKey; +import net.momirealms.craftengine.core.world.Vec3d; +import net.momirealms.craftengine.core.world.Vec3i; import net.momirealms.craftengine.shared.block.BlockBehavior; import org.bukkit.World; import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.Map; +import java.util.Random; import java.util.Set; import java.util.concurrent.Callable; +import java.util.concurrent.ThreadLocalRandom; public class CropBlockBehavior extends BushBlockBehavior { public static final Factory FACTORY = new Factory(); private final IntegerProperty ageProperty; private final float growSpeed; private final int minGrowLight; + private final boolean isBoneMealTarget; + private final NumberProvider boneMealBonus; public CropBlockBehavior(CustomBlock block, List tagsCanSurviveOn, Set blocksCansSurviveOn, Set customBlocksCansSurviveOn, - Property ageProperty, float growSpeed, int minGrowLight) { + Property ageProperty, float growSpeed, int minGrowLight, boolean isBoneMealTarget, NumberProvider boneMealBonus) { super(block, tagsCanSurviveOn, blocksCansSurviveOn, customBlocksCansSurviveOn); this.ageProperty = (IntegerProperty) ageProperty; this.growSpeed = growSpeed; this.minGrowLight = minGrowLight; + this.isBoneMealTarget = isBoneMealTarget; + this.boneMealBonus = boneMealBonus; } public final int getAge(ImmutableBlockState state) { @@ -45,6 +60,22 @@ public class CropBlockBehavior extends BushBlockBehavior { return state.get(ageProperty) == ageProperty.max; } + public float growSpeed() { + return growSpeed; + } + + public boolean isBoneMealTarget() { + return isBoneMealTarget; + } + + public NumberProvider boneMealBonus() { + return boneMealBonus; + } + + public int minGrowLight() { + return minGrowLight; + } + private static int getRawBrightness(Object level, Object pos) throws InvocationTargetException, IllegalAccessException { return (int) Reflections.method$BlockAndTintGetter$getRawBrightness.invoke(level, pos, 0); } @@ -81,6 +112,7 @@ public class CropBlockBehavior extends BushBlockBehavior { @Override public boolean isValidBoneMealTarget(Object thisBlock, Object[] args) { + if (!this.isBoneMealTarget) return false; Object state = args[2]; ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(state)); if (immutableBlockState != null && !immutableBlockState.isEmpty()) { @@ -112,17 +144,22 @@ public class CropBlockBehavior extends BushBlockBehavior { sendParticles = true; } - int i = this.getAge(immutableBlockState) + RandomUtils.generateRandomInt(2, 5); + World world = FastNMS.INSTANCE.method$Level$getCraftWorld(level); + int x = FastNMS.INSTANCE.field$Vec3i$x(pos); + int y = FastNMS.INSTANCE.field$Vec3i$y(pos); + int z = FastNMS.INSTANCE.field$Vec3i$z(pos); + + net.momirealms.craftengine.core.world.World wrappedWorld = new BukkitWorld(world); + int i = this.getAge(immutableBlockState) + this.boneMealBonus.getInt(new LootContext(wrappedWorld, ContextHolder.builder() + .withParameter(LootParameters.WORLD, wrappedWorld) + .withParameter(LootParameters.LOCATION, Vec3d.atCenterOf(new Vec3i(x, y, z))) + .build(), ThreadLocalRandom.current(), 1)); int maxAge = this.ageProperty.max; if (i > maxAge) { i = maxAge; } FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, immutableBlockState.with(this.ageProperty, i).customBlockState().handle(), UpdateOption.UPDATE_NONE.flags()); if (sendParticles) { - World world = FastNMS.INSTANCE.method$Level$getCraftWorld(level); - int x = FastNMS.INSTANCE.field$Vec3i$x(pos); - int y = FastNMS.INSTANCE.field$Vec3i$y(pos); - int z = FastNMS.INSTANCE.field$Vec3i$z(pos); world.spawnParticle(ParticleUtils.getParticle("HAPPY_VILLAGER"), x + 0.5, y + 0.5, z + 0.5, 12, 0.25, 0.25, 0.25); } } @@ -137,10 +174,11 @@ public class CropBlockBehavior extends BushBlockBehavior { if (ageProperty == null) { throw new IllegalArgumentException("age property not set for crop"); } - // 存活条件是最小生长亮度-1 int minGrowLight = MiscUtils.getAsInt(arguments.getOrDefault("light-requirement", 9)); - float growSpeed = MiscUtils.getAsFloat(arguments.getOrDefault("grow-speed", 0.25f)); - return new CropBlockBehavior(block, tuple.left(), tuple.mid(), tuple.right(), ageProperty, growSpeed, minGrowLight); + float growSpeed = MiscUtils.getAsFloat(arguments.getOrDefault("grow-speed", 0.125f)); + boolean isBoneMealTarget = (boolean) arguments.getOrDefault("is-bone-meal-target", true); + NumberProvider boneMealAgeBonus = NumberProviders.fromObject(arguments.getOrDefault("bone-meal-age-bonus", 1)); + return new CropBlockBehavior(block, tuple.left(), tuple.mid(), tuple.right(), ageProperty, growSpeed, minGrowLight, isBoneMealTarget, boneMealAgeBonus); } } } From c98dfb522b3886c256d16f71a62131720ce57901 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Wed, 2 Apr 2025 23:25:14 +0800 Subject: [PATCH 17/19] improve liquid + piston break --- .../bukkit/block/BlockEventListener.java | 115 ++++++++++-------- 1 file changed, 65 insertions(+), 50 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java index 32449e5d6..3bc68b877 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java @@ -184,34 +184,48 @@ public class BlockEventListener implements Listener { } } - // override vanilla block loots + // BlockBreakBlockEvent = liquid + piston @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) public void onBlockBreakBlock(BlockBreakBlockEvent event) { Block block = event.getBlock(); Object blockState = BlockStateUtils.blockDataToBlockState(block.getBlockData()); int stateId = BlockStateUtils.blockStateToId(blockState); if (!BlockStateUtils.isVanillaBlock(stateId)) { - return; - } - this.plugin.vanillaLootManager().getBlockLoot(stateId).ifPresent(it -> { - if (it.override()) { - event.getDrops().clear(); - event.setExpToDrop(0); - } - - Location location = block.getLocation(); - Vec3d vec3d = new Vec3d(location.getBlockX() + 0.5, location.getBlockY() + 0.5, location.getBlockZ() + 0.5); - net.momirealms.craftengine.core.world.World world = new BukkitWorld(location.getWorld()); - ContextHolder.Builder builder = ContextHolder.builder(); - builder.withParameter(LootParameters.WORLD, world); - builder.withParameter(LootParameters.LOCATION, vec3d); - ContextHolder contextHolder = builder.build(); - for (LootTable lootTable : it.lootTables()) { - for (Item item : lootTable.getRandomItems(contextHolder, world)) { + // custom blocks + ImmutableBlockState immutableBlockState = this.manager.getImmutableBlockStateUnsafe(stateId); + if (!immutableBlockState.isEmpty()) { + Location location = block.getLocation(); + net.momirealms.craftengine.core.world.World world = new BukkitWorld(block.getWorld()); + Vec3d vec3d = new Vec3d(location.getBlockX() + 0.5, location.getBlockY() + 0.5, location.getBlockZ() + 0.5); + ContextHolder.Builder builder = ContextHolder.builder(); + builder.withParameter(LootParameters.WORLD, world); + builder.withParameter(LootParameters.LOCATION, vec3d); + for (Item item : immutableBlockState.getDrops(builder, world)) { world.dropItemNaturally(vec3d, item); } } - }); + } else { + // override vanilla block loots + this.plugin.vanillaLootManager().getBlockLoot(stateId).ifPresent(it -> { + if (it.override()) { + event.getDrops().clear(); + event.setExpToDrop(0); + } + + Location location = block.getLocation(); + Vec3d vec3d = new Vec3d(location.getBlockX() + 0.5, location.getBlockY() + 0.5, location.getBlockZ() + 0.5); + net.momirealms.craftengine.core.world.World world = new BukkitWorld(location.getWorld()); + ContextHolder.Builder builder = ContextHolder.builder(); + builder.withParameter(LootParameters.WORLD, world); + builder.withParameter(LootParameters.LOCATION, vec3d); + ContextHolder contextHolder = builder.build(); + for (LootTable lootTable : it.lootTables()) { + for (Item item : lootTable.getRandomItems(contextHolder, world)) { + world.dropItemNaturally(vec3d, item); + } + } + }); + } } @EventHandler(ignoreCancelled = true) @@ -241,37 +255,38 @@ public class BlockEventListener implements Listener { } } - @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) - public void onPistonRetract(BlockPistonRetractEvent event) { - handlePistonEvent(event.getDirection(), event.getBlocks(), event.getBlock()); - } - - @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) - public void onPistonExtend(BlockPistonExtendEvent event) { - handlePistonEvent(event.getDirection(), event.getBlocks(), event.getBlock()); - } - - private void handlePistonEvent(BlockFace face, List blocksList, Block piston) { - int blocks = blocksList.size(); - net.momirealms.craftengine.core.world.World world = new BukkitWorld(piston.getWorld()); - for (int i = blocks - 1; i >= 0; --i) { - Location oldLocation = blocksList.get(i).getLocation(); - BlockPos oldPos = new BlockPos(oldLocation.getBlockX(), oldLocation.getBlockY(), oldLocation.getBlockZ()); - Block block = blocksList.get(i); - ImmutableBlockState blockState = manager.getImmutableBlockState(BlockStateUtils.blockDataToId(block.getBlockData())); - if (blockState != null && blockState.pushReaction() == PushReaction.DESTROY) { - // break actions - ContextHolder.Builder builder = ContextHolder.builder(); - Vec3d vec3d = Vec3d.atCenterOf(oldPos); - builder.withParameter(LootParameters.LOCATION, vec3d); - builder.withParameter(LootParameters.WORLD, world); - for (Item item : blockState.getDrops(builder, world)) { - world.dropItemNaturally(vec3d, item); - } - world.playBlockSound(vec3d, blockState.sounds().breakSound()); - } - } - } +// Use BlockBreakBlock event +// @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) +// public void onPistonRetract(BlockPistonRetractEvent event) { +// handlePistonEvent(event.getDirection(), event.getBlocks(), event.getBlock()); +// } +// +// @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) +// public void onPistonExtend(BlockPistonExtendEvent event) { +// handlePistonEvent(event.getDirection(), event.getBlocks(), event.getBlock()); +// } +// +// private void handlePistonEvent(BlockFace face, List blocksList, Block piston) { +// int blocks = blocksList.size(); +// net.momirealms.craftengine.core.world.World world = new BukkitWorld(piston.getWorld()); +// for (int i = blocks - 1; i >= 0; --i) { +// Location oldLocation = blocksList.get(i).getLocation(); +// BlockPos oldPos = new BlockPos(oldLocation.getBlockX(), oldLocation.getBlockY(), oldLocation.getBlockZ()); +// Block block = blocksList.get(i); +// ImmutableBlockState blockState = manager.getImmutableBlockState(BlockStateUtils.blockDataToId(block.getBlockData())); +// if (blockState != null && blockState.pushReaction() == PushReaction.DESTROY) { +// // break actions +// ContextHolder.Builder builder = ContextHolder.builder(); +// Vec3d vec3d = Vec3d.atCenterOf(oldPos); +// builder.withParameter(LootParameters.LOCATION, vec3d); +// builder.withParameter(LootParameters.WORLD, world); +// for (Item item : blockState.getDrops(builder, world)) { +// world.dropItemNaturally(vec3d, item); +// } +// world.playBlockSound(vec3d, blockState.sounds().breakSound()); +// } +// } +// } @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) public void onEntityExplode(EntityExplodeEvent event) { From c638c263702fd66ce50465c01011fbac06c31dcf Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Wed, 2 Apr 2025 23:26:43 +0800 Subject: [PATCH 18/19] Update gradle.properties --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 4c86a43c1..005ca4cf7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.41 +project_version=0.0.42 config_version=19 lang_version=3 project_group=net.momirealms From 6e0a3b2b26efcbd81f3509f0b0fafaadde70a9ae Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Wed, 2 Apr 2025 23:27:25 +0800 Subject: [PATCH 19/19] update readme --- README.md | 4 ++-- readme/README_zh-CN.md | 4 ++-- readme/README_zh-TW.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d766c3f46..d1a6aa1e9 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,7 @@ repositories { ``` ```kotlin dependencies { - compileOnly("net.momirealms:craft-engine-core:0.0.38") - compileOnly("net.momirealms:craft-engine-bukkit:0.0.38") + compileOnly("net.momirealms:craft-engine-core:0.0.42") + compileOnly("net.momirealms:craft-engine-bukkit:0.0.42") } ``` diff --git a/readme/README_zh-CN.md b/readme/README_zh-CN.md index e5a08026c..14402d3f0 100644 --- a/readme/README_zh-CN.md +++ b/readme/README_zh-CN.md @@ -126,7 +126,7 @@ repositories { ``` ```kotlin dependencies { - compileOnly("net.momirealms:craft-engine-core:0.0.38") - compileOnly("net.momirealms:craft-engine-bukkit:0.0.38") + compileOnly("net.momirealms:craft-engine-core:0.0.42") + compileOnly("net.momirealms:craft-engine-bukkit:0.0.42") } ``` diff --git a/readme/README_zh-TW.md b/readme/README_zh-TW.md index 9191c8b3b..803803490 100644 --- a/readme/README_zh-TW.md +++ b/readme/README_zh-TW.md @@ -126,7 +126,7 @@ repositories { ``` ```kotlin dependencies { - compileOnly("net.momirealms:craft-engine-core:0.0.38") - compileOnly("net.momirealms:craft-engine-bukkit:0.0.38") + compileOnly("net.momirealms:craft-engine-core:0.0.42") + compileOnly("net.momirealms:craft-engine-bukkit:0.0.42") } ```