From 493601fb11fed3f3666aee3a4207692ba5573f9e Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Tue, 22 Apr 2025 17:19:06 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E5=A5=BD=E7=9A=84=E7=A2=B0=E6=92=9E?= =?UTF-8?q?=E6=96=B9=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bukkit/loader/src/main/resources/config.yml | 5 ++- .../entity/furniture/BukkitCollider.java | 14 +++---- .../furniture/BukkitFurnitureManager.java | 37 ++++++++++++------- .../furniture/FurnitureEventListener.java | 23 +++++++----- .../furniture/hitbox/InteractionHitBox.java | 5 +-- .../furniture/hitbox/ShulkerHitBox.java | 5 +-- .../item/behavior/FurnitureItemBehavior.java | 1 - .../plugin/network/PacketConsumers.java | 2 +- .../craftengine/bukkit/util/Reflections.java | 3 ++ .../core/entity/furniture/Collider.java | 2 - .../core/entity/furniture/ColliderType.java | 3 +- .../core/plugin/config/Config.java | 10 ++++- gradle.properties | 2 +- .../craftengine/mod/CraftEnginePlugin.java | 1 - 14 files changed, 63 insertions(+), 50 deletions(-) diff --git a/bukkit/loader/src/main/resources/config.yml b/bukkit/loader/src/main/resources/config.yml index a856e873c..63d41c3b3 100644 --- a/bukkit/loader/src/main/resources/config.yml +++ b/bukkit/loader/src/main/resources/config.yml @@ -170,12 +170,15 @@ furniture: # Converts the invalid furniture to a valid one convert: "namespace:furniture_a": "namespace:furniture_b" - # Hide technical entities used for storing furniture metadata. # NOTE: # - These are INVISIBLE entities used internally for tracking furniture states # - Recommended to keep enabled for better performance hide-base-entity: true + # Requires a restart to apply + # interaction (best performance) + # boat (better compatibility with some anti-cheat plugin) + collision-entity-type: interaction emoji: chat: true diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitCollider.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitCollider.java index f2d94e95f..69b8c9775 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitCollider.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitCollider.java @@ -1,16 +1,17 @@ package net.momirealms.craftengine.bukkit.entity.furniture; import net.momirealms.craftengine.bukkit.nms.CollisionEntity; +import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.core.entity.furniture.Collider; import net.momirealms.craftengine.core.entity.furniture.ColliderType; public class BukkitCollider implements Collider { private final CollisionEntity collisionEntity; - private final ColliderType type; - public BukkitCollider(CollisionEntity collisionEntity, ColliderType type) { - this.collisionEntity = collisionEntity; - this.type = type; + public BukkitCollider(Object world, Object aabb, double x, double y, double z, boolean canProjectileHit, boolean canCollide, boolean blocksBuilding) { + this.collisionEntity = BukkitFurnitureManager.COLLISION_ENTITY_TYPE == ColliderType.INTERACTION ? + FastNMS.INSTANCE.createCollisionInteraction(world, aabb, x, y, z, canProjectileHit, canCollide, blocksBuilding) : + FastNMS.INSTANCE.createCollisionBoat(world, aabb, x, y, z, canProjectileHit, canCollide, blocksBuilding); } @Override @@ -23,11 +24,6 @@ public class BukkitCollider implements Collider { return this.collisionEntity.getId(); } - @Override - public ColliderType type() { - return this.type; - } - @Override public Object handle() { return this.collisionEntity; 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 e3a5c2fe5..aaac3644b 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 @@ -39,6 +39,9 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager { public static final NamespacedKey FURNITURE_SEAT_BASE_ENTITY_KEY = Objects.requireNonNull(NamespacedKey.fromString("craftengine:seat_to_base_entity")); public static final NamespacedKey FURNITURE_SEAT_VECTOR_3F_KEY = Objects.requireNonNull(NamespacedKey.fromString("craftengine:seat_vector")); public static final NamespacedKey FURNITURE_COLLISION = Objects.requireNonNull(NamespacedKey.fromString("craftengine:collision")); + public static Class COLLISION_ENTITY_CLASS = Interaction.class; + public static Object NMS_COLLISION_ENTITY_TYPE = Reflections.instance$EntityType$INTERACTION; + public static ColliderType COLLISION_ENTITY_TYPE = ColliderType.INTERACTION; private static BukkitFurnitureManager instance; private final BukkitCraftEngine plugin; private final FurnitureParser furnitureParser; @@ -204,6 +207,9 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager { @Override public void delayedInit() { + COLLISION_ENTITY_CLASS = Config.colliderType() == ColliderType.INTERACTION ? Interaction.class : Boat.class; + NMS_COLLISION_ENTITY_TYPE = Config.colliderType() == ColliderType.INTERACTION ? Reflections.instance$EntityType$INTERACTION : Reflections.instance$EntityType$OAK_BOAT; + COLLISION_ENTITY_TYPE = Config.colliderType(); Bukkit.getPluginManager().registerEvents(this.dismountListener, this.plugin.bootstrap()); Bukkit.getPluginManager().registerEvents(this.furnitureEventListener, this.plugin.bootstrap()); for (World world : Bukkit.getWorlds()) { @@ -211,8 +217,11 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager { for (Entity entity : entities) { if (entity instanceof ItemDisplay display) { handleBaseEntityLoadEarly(display); - } else if (entity instanceof Interaction interaction) { - handleCollisionEntityLoadOnEntitiesLoad(interaction); + } else if (COLLISION_ENTITY_CLASS.isInstance(entity)) { + handleCollisionEntityLoadOnEntitiesLoad(entity); + } else if (entity instanceof Shulker shulker) { + // TODO 移除这一行,预计过一个月 + handleCollisionEntityLoadOnEntitiesLoad(shulker); } } } @@ -310,29 +319,29 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager { this.plugin.scheduler().sync().runLater(() -> handleBaseEntityLoadLate(display, depth + 1), 1, location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4); } - protected void handleCollisionEntityLoadLate(Interaction interaction, int depth) { - // remove the interaction if it's not a collision entity, it might be wrongly copied by WorldEdit - if (FastNMS.INSTANCE.method$CraftEntity$getHandle(interaction) instanceof CollisionEntity) { + protected void handleCollisionEntityLoadLate(Entity entity, int depth) { + // remove the entity if it's not a collision entity, it might be wrongly copied by WorldEdit + if (FastNMS.INSTANCE.method$CraftEntity$getHandle(entity) instanceof CollisionEntity) { return; } // not a collision entity - Byte flag = interaction.getPersistentDataContainer().get(FURNITURE_COLLISION, PersistentDataType.BYTE); + Byte flag = entity.getPersistentDataContainer().get(FURNITURE_COLLISION, PersistentDataType.BYTE); if (flag == null || flag != 1) { return; } - Location location = interaction.getLocation(); + Location location = entity.getLocation(); World world = location.getWorld(); int chunkX = location.getBlockX() >> 4; int chunkZ = location.getBlockZ() >> 4; if (!FastNMS.INSTANCE.isPreventingStatusUpdates(world, chunkX, chunkZ)) { - interaction.remove(); + entity.remove(); return; } if (depth > 2) return; plugin.scheduler().sync().runLater(() -> { - handleCollisionEntityLoadLate(interaction, depth + 1); + handleCollisionEntityLoadLate(entity, depth + 1); }, 1, world, chunkX, chunkZ); } @@ -364,20 +373,20 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager { } } - public void handleCollisionEntityLoadOnEntitiesLoad(Interaction interaction) { + public void handleCollisionEntityLoadOnEntitiesLoad(Entity collisionEntity) { // faster - if (FastNMS.INSTANCE.method$CraftEntity$getHandle(interaction) instanceof CollisionEntity) { - interaction.remove(); + if (FastNMS.INSTANCE.method$CraftEntity$getHandle(collisionEntity) instanceof CollisionEntity) { + collisionEntity.remove(); return; } // not a collision entity - Byte flag = interaction.getPersistentDataContainer().get(FURNITURE_COLLISION, PersistentDataType.BYTE); + Byte flag = collisionEntity.getPersistentDataContainer().get(FURNITURE_COLLISION, PersistentDataType.BYTE); if (flag == null || flag != 1) { return; } - interaction.remove(); + collisionEntity.remove(); } private AnchorType getAnchorType(Entity baseEntity, CustomFurniture furniture) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/FurnitureEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/FurnitureEventListener.java index d3d9b2a87..f9c526233 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/FurnitureEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/FurnitureEventListener.java @@ -2,7 +2,10 @@ package net.momirealms.craftengine.bukkit.entity.furniture; import com.destroystokyo.paper.event.entity.EntityAddToWorldEvent; import com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent; -import org.bukkit.entity.*; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.ItemDisplay; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -33,8 +36,8 @@ public class FurnitureEventListener implements Listener { for (Entity entity : entities) { if (entity instanceof ItemDisplay itemDisplay) { this.manager.handleBaseEntityLoadEarly(itemDisplay); - } else if (entity instanceof Interaction interaction) { - this.manager.handleCollisionEntityLoadOnEntitiesLoad(interaction); + } else if (BukkitFurnitureManager.COLLISION_ENTITY_CLASS.isInstance(entity)) { + this.manager.handleCollisionEntityLoadOnEntitiesLoad(entity); } } } @@ -45,8 +48,8 @@ public class FurnitureEventListener implements Listener { for (Entity entity : entities) { if (entity instanceof ItemDisplay itemDisplay) { this.manager.handleBaseEntityLoadEarly(itemDisplay); - } else if (entity instanceof Interaction interaction) { - this.manager.handleCollisionEntityLoadOnEntitiesLoad(interaction); + } else if (BukkitFurnitureManager.COLLISION_ENTITY_CLASS.isInstance(entity)) { + this.manager.handleCollisionEntityLoadOnEntitiesLoad(entity); } } } @@ -56,8 +59,8 @@ public class FurnitureEventListener implements Listener { Entity entity = event.getEntity(); if (entity instanceof ItemDisplay itemDisplay) { this.manager.handleBaseEntityLoadLate(itemDisplay, 0); - } else if (entity instanceof Interaction interaction) { - this.manager.handleCollisionEntityLoadLate(interaction, 0); + } else if (BukkitFurnitureManager.COLLISION_ENTITY_CLASS.isInstance(entity)) { + this.manager.handleCollisionEntityLoadLate(entity, 0); } } @@ -70,7 +73,7 @@ public class FurnitureEventListener implements Listener { for (Entity entity : entities) { if (entity instanceof ItemDisplay) { this.manager.handleBaseEntityUnload(entity); - } else if (entity instanceof Interaction) { + } else if (BukkitFurnitureManager.COLLISION_ENTITY_CLASS.isInstance(entity)) { this.manager.handleCollisionEntityUnload(entity); } } @@ -82,7 +85,7 @@ public class FurnitureEventListener implements Listener { for (Entity entity : entities) { if (entity instanceof ItemDisplay) { this.manager.handleBaseEntityUnload(entity); - } else if (entity instanceof Interaction) { + } else if (BukkitFurnitureManager.COLLISION_ENTITY_CLASS.isInstance(entity)) { this.manager.handleCollisionEntityUnload(entity); } } @@ -93,7 +96,7 @@ public class FurnitureEventListener implements Listener { Entity entity = event.getEntity(); if (entity instanceof ItemDisplay) { this.manager.handleBaseEntityUnload(entity); - } else if (entity instanceof Interaction) { + } else if (BukkitFurnitureManager.COLLISION_ENTITY_CLASS.isInstance(entity)) { this.manager.handleCollisionEntityUnload(entity); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/InteractionHitBox.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/InteractionHitBox.java index a06ead6f7..fa21617cc 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/InteractionHitBox.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/InteractionHitBox.java @@ -65,10 +65,7 @@ public class InteractionHitBox extends AbstractHitBox { if (blocksBuilding() || this.canBeHitByProjectile()) { AABB ceAABB = AABB.fromInteraction(new Vec3d(x + offset.x, y + offset.y, z - offset.z), this.size.x, this.size.y); Object nmsAABB = FastNMS.INSTANCE.constructor$AABB(ceAABB.minX, ceAABB.minY, ceAABB.minZ, ceAABB.maxX, ceAABB.maxY, ceAABB.maxZ); - collider.accept(new BukkitCollider( - FastNMS.INSTANCE.createCollisionInteraction(world.serverWorld(), nmsAABB, x, y, z, this.canBeHitByProjectile(), false, this.blocksBuilding()), - ColliderType.SHULKER - )); + collider.accept(new BukkitCollider(world.serverWorld(), nmsAABB, x, y, z, this.canBeHitByProjectile(), false, this.blocksBuilding())); } } 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 f69e947f6..130a9bd36 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 @@ -127,10 +127,7 @@ public class ShulkerHitBox extends AbstractHitBox { Object level = world.serverWorld(); Object nmsAABB = FastNMS.INSTANCE.constructor$AABB(ceAABB.minX, ceAABB.minY, ceAABB.minZ, ceAABB.maxX, ceAABB.maxY, ceAABB.maxZ); aabb.accept(entityId, ceAABB); - return new BukkitCollider( - FastNMS.INSTANCE.createCollisionInteraction(level, nmsAABB, x, y, z, this.canBeHitByProjectile(), true, this.blocksBuilding()), - ColliderType.SHULKER - ); + return new BukkitCollider(level, nmsAABB, x, y, z, this.canBeHitByProjectile(), true, this.blocksBuilding()); } public AABB createAABB(Direction direction, Vector3f offset, double x, double y, double z) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/FurnitureItemBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/FurnitureItemBehavior.java index 3c0d02793..ca01dba72 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/FurnitureItemBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/FurnitureItemBehavior.java @@ -24,7 +24,6 @@ import net.momirealms.craftengine.core.world.Vec3d; import net.momirealms.craftengine.core.world.collision.AABB; import org.bukkit.Location; import org.bukkit.World; -import org.joml.Quaternionf; import java.nio.file.Path; import java.util.ArrayList; 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 c52493d96..719667520 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 @@ -1516,7 +1516,7 @@ public class PacketConsumers { event.setCancelled(true); } } - } else if (entityType == Reflections.instance$EntityType$INTERACTION) { + } else if (entityType == BukkitFurnitureManager.NMS_COLLISION_ENTITY_TYPE) { // Cancel collider entity packet int entityId = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$entityId(packet); LoadedFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(entityId); 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 5d51c0923..d823eeacc 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 @@ -3773,6 +3773,7 @@ public class Reflections { public static final Object instance$EntityType$FALLING_BLOCK; public static final Object instance$EntityType$INTERACTION; public static final Object instance$EntityType$SHULKER; + public static final Object instance$EntityType$OAK_BOAT; static { try { @@ -3790,6 +3791,8 @@ public class Reflections { instance$EntityType$SHULKER = Reflections.method$Registry$get.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, shulker); Object armorStand = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "armor_stand"); instance$EntityType$ARMOR_STAND = Reflections.method$Registry$get.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, armorStand); + Object oakBoat = VersionHelper.isVersionNewerThan1_21_2() ? FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "oak_boat") : FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "boat"); + instance$EntityType$OAK_BOAT = Reflections.method$Registry$get.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, oakBoat); } catch (ReflectiveOperationException e) { throw new RuntimeException(e); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/Collider.java b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/Collider.java index fccdbc3f8..a52ab66c4 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/Collider.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/Collider.java @@ -6,7 +6,5 @@ public interface Collider { int entityId(); - ColliderType type(); - Object handle(); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/ColliderType.java b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/ColliderType.java index c935a40c8..6324d2abd 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/ColliderType.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/ColliderType.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.entity.furniture; public enum ColliderType { - SHULKER + INTERACTION, + BOAT } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java index f423f8265..fffc622f2 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java @@ -12,6 +12,7 @@ import dev.dejvokep.boostedyaml.settings.loader.LoaderSettings; import dev.dejvokep.boostedyaml.settings.updater.UpdaterSettings; import dev.dejvokep.boostedyaml.utils.format.NodeRole; import net.kyori.adventure.text.Component; +import net.momirealms.craftengine.core.entity.furniture.ColliderType; import net.momirealms.craftengine.core.pack.conflict.resolution.ConditionalResolution; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.PluginProperties; @@ -32,6 +33,7 @@ import java.lang.reflect.Method; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @@ -100,6 +102,7 @@ public class Config { protected boolean furniture$handle_invalid_furniture_on_chunk_load$enable; protected Map furniture$handle_invalid_furniture_on_chunk_load$mapping; protected boolean furniture$hide_base_entity; + protected ColliderType furniture$collision_entity_type; protected boolean block$sound_system$enable; protected boolean block$simplify_adventure_break_check; @@ -277,9 +280,10 @@ public class Config { } } } - this.furniture$handle_invalid_furniture_on_chunk_load$mapping = builder.build(); + furniture$handle_invalid_furniture_on_chunk_load$mapping = builder.build(); furniture$hide_base_entity = config.getBoolean("furniture.hide-base-entity", true); + furniture$collision_entity_type = ColliderType.valueOf(config.getString("furniture.collision-entity-type", "interaction").toUpperCase(Locale.ENGLISH)); // block block$sound_system$enable = config.getBoolean("block.sound-system.enable", true); @@ -675,6 +679,10 @@ public class Config { return instance.emoji$book; } + public static ColliderType colliderType() { + return instance.furniture$collision_entity_type; + } + public YamlDocument loadOrCreateYamlData(String fileName) { File file = new File(this.plugin.dataFolderFile(), fileName); if (!file.exists()) { diff --git a/gradle.properties b/gradle.properties index 001a6ca89..eb9d4ba4a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -51,7 +51,7 @@ byte_buddy_version=1.17.5 ahocorasick_version=0.6.3 snake_yaml_version=2.4 anti_grief_version=0.15 -nms_helper_version=0.60.14 +nms_helper_version=0.61 reactive_streams_version=1.0.4 amazon_awssdk_version=2.31.23 amazon_awssdk_eventstream_version=1.0.1 diff --git a/server-mod/v1_21_5/src/main/java/net/momirealms/craftengine/mod/CraftEnginePlugin.java b/server-mod/v1_21_5/src/main/java/net/momirealms/craftengine/mod/CraftEnginePlugin.java index 1595c9ccd..6cb356a90 100644 --- a/server-mod/v1_21_5/src/main/java/net/momirealms/craftengine/mod/CraftEnginePlugin.java +++ b/server-mod/v1_21_5/src/main/java/net/momirealms/craftengine/mod/CraftEnginePlugin.java @@ -1,6 +1,5 @@ package net.momirealms.craftengine.mod; -import net.minecraft.server.level.ServerLevel; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.objectweb.asm.tree.ClassNode;