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 c59ef90bd..d9a512893 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 @@ -48,7 +48,6 @@ public class TestCommand extends BukkitCommandFeature { return CompletableFuture.completedFuture(plugin().itemManager().cachedSuggestions()); } })) - .required("interpolationDuration", IntegerParser.integerParser()) .required("displayType", ByteParser.byteParser((byte) 0, (byte) 8)) .required("translation", StringParser.stringParser()) .required("rotationLeft", StringParser.stringParser()) @@ -57,12 +56,6 @@ public class TestCommand extends BukkitCommandFeature { NamespacedKey namespacedKey = context.get("id"); ItemStack item = new ItemStack(Material.TRIDENT); item.editMeta((meta) -> { - PersistentDataContainer container = meta.getPersistentDataContainer(); - container.set(CustomTridentUtils.customTridentKey, PersistentDataType.STRING, namespacedKey.asString()); - container.set(CustomTridentUtils.interpolationDurationaKey, PersistentDataType.INTEGER, context.get("interpolationDuration")); - container.set(CustomTridentUtils.displayTypeKey, PersistentDataType.BYTE, context.get("displayType")); - container.set(CustomTridentUtils.translationKey, PersistentDataType.STRING, context.get("translation")); - container.set(CustomTridentUtils.rotationLeftKey, PersistentDataType.STRING, context.get("rotationLeft")); Item ceItem = BukkitItemManager.instance().createWrappedItem(Key.of(namespacedKey.asString()), null); Optional customModelData = ceItem.customModelData(); customModelData.ifPresent(meta::setCustomModelData); 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 0ab795316..183b20b31 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 @@ -1621,7 +1621,7 @@ public class PacketConsumers { try { int entityId = FastNMS.INSTANCE.method$ClientboundEntityPositionSyncPacket$id(packet); if (user.tridentView().containsKey(entityId)) { - CustomTridentUtils.modifyCustomTridentPositionSync(event, packet, entityId); + event.replacePacket(CustomTridentUtils.buildCustomTridentPositionSync(packet, entityId)); return; } if (BukkitFurnitureManager.instance().isFurnitureRealEntity(entityId)) { @@ -2345,7 +2345,7 @@ public class PacketConsumers { try { int entityId = BukkitInjector.internalFieldAccessor().field$ClientboundMoveEntityPacket$entityId(packet); if (user.tridentView().containsKey(entityId)) { - CustomTridentUtils.modifyCustomTridentMove(packet); + event.replacePacket(CustomTridentUtils.buildCustomTridentMove(packet, entityId)); } } catch (Exception e) { CraftEngine.instance().logger().warn("Failed to handle ClientboundMoveEntityPacket$PosRot", e); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/CustomTridentUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/CustomTridentUtils.java index 5c4c270e2..7f87849de 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/CustomTridentUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/CustomTridentUtils.java @@ -4,6 +4,8 @@ import net.momirealms.craftengine.bukkit.entity.data.ItemDisplayEntityData; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.network.NMSPacketEvent; +import net.momirealms.craftengine.core.entity.CustomTrident; +import net.momirealms.craftengine.core.item.CustomItem; import net.momirealms.craftengine.core.item.Enchantment; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.plugin.CraftEngine; @@ -12,74 +14,51 @@ import net.momirealms.craftengine.core.plugin.scheduler.SchedulerTask; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MCUtils; import net.momirealms.craftengine.core.util.VersionHelper; -import org.bukkit.NamespacedKey; import org.bukkit.World; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.entity.Trident; import org.bukkit.inventory.ItemStack; -import org.bukkit.persistence.PersistentDataContainer; -import org.bukkit.persistence.PersistentDataType; -import org.joml.Quaternionf; -import org.joml.Vector3f; import javax.annotation.Nullable; -import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; -import java.util.Objects; +import java.util.Optional; +import java.util.UUID; import java.util.concurrent.TimeUnit; public class CustomTridentUtils { - public static final NamespacedKey customTridentKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:custom_trident")); - public static final NamespacedKey interpolationDurationaKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:interpolation_duration")); - public static final NamespacedKey displayTypeKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:display_type")); - public static final NamespacedKey translationKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:translation")); - public static final NamespacedKey rotationLeftKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:rotation_left")); - public static void handleCustomTrident(NetWorkUser user, NMSPacketEvent event, Object packet) throws IllegalAccessException { + public static void handleCustomTrident(NetWorkUser user, NMSPacketEvent event, Object packet) { int entityId = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$entityId(packet); Trident trident = getTridentById(user, entityId); if (trident == null) return; World world = trident.getWorld(); - Object serverEntity; Object nmsEntity = FastNMS.INSTANCE.method$CraftEntity$getHandle(trident); - Object tracker = Reflections.field$Entity$trackedEntity.get(nmsEntity); - if (tracker != null) { - serverEntity = Reflections.field$ChunkMap$TrackedEntity$serverEntity.get(tracker); - } else { - serverEntity = null; - } + Object trackedEntity = FastNMS.INSTANCE.field$Entity$trackedEntity(nmsEntity); + Object serverEntity = FastNMS.INSTANCE.filed$ChunkMap$TrackedEntity$serverEntity(trackedEntity); if (notCustomTrident(trident)) return; - modifyCustomTridentPacket(packet); + Object newPacket = modifyCustomTridentPacket(packet, entityId); List itemDisplayValues = buildEntityDataValues(trident); user.tridentView().put(entityId, itemDisplayValues); - user.sendPacket(packet, true); + user.sendPacket(newPacket, true); user.sendPacket(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId, itemDisplayValues), true); event.setCancelled(true); if (serverEntity != null) { // 这里直接暴力更新 SchedulerTask task = CraftEngine.instance().scheduler().asyncRepeating(() -> { - try { - Reflections.method$ServerEntity$sendChanges.invoke(serverEntity); - if (!isInGround(nmsEntity)) { - world.spawnParticle(ParticleUtils.getParticle("BUBBLE"), trident.getLocation(), 1, 0, 0, 0, 0); - } - } catch (IllegalAccessException | InvocationTargetException e) { - CraftEngine.instance().logger().warn("Failed to send entity data packet", e); + FastNMS.INSTANCE.method$ServerEntity$sendChanges(serverEntity); + if (canSpawnParticle(nmsEntity)) { + world.spawnParticle(ParticleUtils.getParticle("BUBBLE"), trident.getLocation(), 1, 0, 0, 0, 0); } }, 0, 5, TimeUnit.MILLISECONDS); user.tridentTaskView().put(entityId, task); } } - private static boolean isInGround(Object nmsEntity) throws IllegalAccessException, InvocationTargetException { - if (!Reflections.field$Entity$wasTouchingWater.getBoolean(nmsEntity)) return true; - if (VersionHelper.isOrAbove1_21_2()) { - return (boolean) Reflections.method$AbstractArrow$isInGround.invoke(nmsEntity); - } else { - return Reflections.field$AbstractArrow$inGround.getBoolean(nmsEntity); - } + private static boolean canSpawnParticle(Object nmsEntity) { + if (!FastNMS.INSTANCE.field$AbstractArrow$wasTouchingWater(nmsEntity)) return false; + return !FastNMS.INSTANCE.method$AbstractArrow$isInGround(nmsEntity); } @Nullable @@ -92,62 +71,75 @@ public class CustomTridentUtils { public static boolean notCustomTrident(Trident trident) { if (trident == null) return true; - PersistentDataContainer container = trident.getItemStack().getItemMeta().getPersistentDataContainer(); - String customTrident = container.get(customTridentKey, PersistentDataType.STRING); - return customTrident == null; + Optional> customItem = BukkitItemManager.instance().wrap(trident.getItemStack()).getCustomItem(); + return customItem.map(itemStackCustomItem -> itemStackCustomItem.settings().customTrident() == null).orElse(true); } - public static void modifyCustomTridentPacket(Object packet) throws IllegalAccessException { - float yRot = MCUtils.unpackDegrees(Reflections.field$ClientboundAddEntityPacket$yRot.getByte(packet)); - float xRot = MCUtils.unpackDegrees(Reflections.field$ClientboundAddEntityPacket$xRot.getByte(packet)); - Reflections.field$ClientboundAddEntityPacket$type.set(packet, Reflections.instance$EntityType$ITEM_DISPLAY); - Reflections.field$ClientboundAddEntityPacket$yRot.setByte(packet, MCUtils.packDegrees(-yRot)); - Reflections.field$ClientboundAddEntityPacket$xRot.setByte(packet, MCUtils.packDegrees(Math.clamp(-xRot, -90.0F, 90.0F))); + public static Object modifyCustomTridentPacket(Object packet, int entityId) { + UUID uuid = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$uuid(packet); + double x = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$x(packet); + double y = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$y(packet); + double z = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$z(packet); + float yRot = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$yRot(packet); + float xRot = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$xRot(packet); + Object type = Reflections.instance$EntityType$ITEM_DISPLAY; + int data = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$data(packet); + double xa = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$xa(packet); + double ya = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$ya(packet); + double za = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$za(packet); + double yHeadRot = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$yHeadRot(packet); + return FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( + entityId, uuid, x, y, z, + MCUtils.clamp(-xRot, -90.0F, 90.0F), -yRot, + type, data, FastNMS.INSTANCE.constructor$Vec3(xa, ya, za), yHeadRot + ); } public static List buildEntityDataValues(Trident trident) { List itemDisplayValues = new ArrayList<>(); ItemStack itemStack = trident.getItemStack(); - PersistentDataContainer container = itemStack.getItemMeta().getPersistentDataContainer(); - String customTrident = container.getOrDefault(customTridentKey, PersistentDataType.STRING, "craftengine:empty"); - Item item = BukkitItemManager.instance().createWrappedItem(Key.of(customTrident), null); + Optional> customItem = BukkitItemManager.instance().wrap(itemStack).getCustomItem(); + if (customItem.isEmpty()) return itemDisplayValues; + CustomTrident customTrident = customItem.get().settings().customTrident(); + Item item = BukkitItemManager.instance().createWrappedItem(customTrident.customTridentItemId(), null); itemStack.getEnchantments().forEach((enchantment, level) -> item.addEnchantment(new Enchantment(Key.of(enchantment.getKey().toString()), level))); - Integer interpolationDurationa = container.getOrDefault(interpolationDurationaKey, PersistentDataType.INTEGER, 2); - Byte displayType = container.getOrDefault(displayTypeKey, PersistentDataType.BYTE, (byte) 0); - String translation = container.getOrDefault(translationKey, PersistentDataType.STRING, "0+0+0"); - String[] translations = translation.split("\\+"); - String rotationLeft = container.getOrDefault(rotationLeftKey, PersistentDataType.STRING, "0+0+0+0"); - String[] rotationLefts = rotationLeft.split("\\+"); ItemDisplayEntityData.InterpolationDelay.addEntityDataIfNotDefaultValue(-1, itemDisplayValues); - ItemDisplayEntityData.Translation.addEntityDataIfNotDefaultValue(new Vector3f(Float.parseFloat(translations[0]), Float.parseFloat(translations[1]), Float.parseFloat(translations[2])), itemDisplayValues); - ItemDisplayEntityData.RotationLeft.addEntityDataIfNotDefaultValue(new Quaternionf(Float.parseFloat(rotationLefts[0]), Float.parseFloat(rotationLefts[1]), Float.parseFloat(rotationLefts[2]), Float.parseFloat(rotationLefts[3])), itemDisplayValues); + ItemDisplayEntityData.Translation.addEntityDataIfNotDefaultValue(customTrident.translation(), itemDisplayValues); + ItemDisplayEntityData.RotationLeft.addEntityDataIfNotDefaultValue(customTrident.rotationLefts(), itemDisplayValues); if (VersionHelper.isOrAbove1_20_2()) { - ItemDisplayEntityData.TransformationInterpolationDuration.addEntityDataIfNotDefaultValue(interpolationDurationa, itemDisplayValues); - ItemDisplayEntityData.PositionRotationInterpolationDuration.addEntityDataIfNotDefaultValue(interpolationDurationa, itemDisplayValues); + ItemDisplayEntityData.TransformationInterpolationDuration.addEntityDataIfNotDefaultValue(2, itemDisplayValues); + ItemDisplayEntityData.PositionRotationInterpolationDuration.addEntityDataIfNotDefaultValue(2, itemDisplayValues); } else { - ItemDisplayEntityData.InterpolationDuration.addEntityDataIfNotDefaultValue(interpolationDurationa, itemDisplayValues); + ItemDisplayEntityData.InterpolationDuration.addEntityDataIfNotDefaultValue(2, itemDisplayValues); } ItemDisplayEntityData.DisplayedItem.addEntityDataIfNotDefaultValue(item.getLiteralObject(), itemDisplayValues); - ItemDisplayEntityData.DisplayType.addEntityDataIfNotDefaultValue(displayType, itemDisplayValues); + ItemDisplayEntityData.DisplayType.addEntityDataIfNotDefaultValue(customTrident.displayType(), itemDisplayValues); return itemDisplayValues; } - public static void modifyCustomTridentPositionSync(NMSPacketEvent event, Object packet, int entityId) throws IllegalAccessException, InvocationTargetException, InstantiationException { - Object positionMoveRotation = Reflections.field$ClientboundEntityPositionSyncPacket$values.get(packet); - boolean onGround = Reflections.field$ClientboundEntityPositionSyncPacket$onGround.getBoolean(packet); - Object position = Reflections.field$PositionMoveRotation$position.get(positionMoveRotation); - Object deltaMovement = Reflections.field$PositionMoveRotation$deltaMovement.get(positionMoveRotation); - float yRot = Reflections.field$PositionMoveRotation$yRot.getFloat(positionMoveRotation); - float xRot = Reflections.field$PositionMoveRotation$xRot.getFloat(positionMoveRotation); - Object newPositionMoveRotation = Reflections.constructor$PositionMoveRotation.newInstance(position, deltaMovement, -yRot, Math.clamp(-xRot, -90.0F, 90.0F)); - event.replacePacket(Reflections.constructor$ClientboundEntityPositionSyncPacket.newInstance(entityId, newPositionMoveRotation, onGround)); + public static Object buildCustomTridentPositionSync(Object packet, int entityId) { + Object positionMoveRotation = FastNMS.INSTANCE.field$ClientboundEntityPositionSyncPacket$values(packet); + boolean onGround = FastNMS.INSTANCE.field$ClientboundEntityPositionSyncPacket$onGround(packet); + Object position = FastNMS.INSTANCE.field$PositionMoveRotation$position(positionMoveRotation); + Object deltaMovement = FastNMS.INSTANCE.field$PositionMoveRotation$deltaMovement(positionMoveRotation); + float yRot = FastNMS.INSTANCE.field$PositionMoveRotation$yRot(positionMoveRotation); + float xRot = FastNMS.INSTANCE.field$PositionMoveRotation$xRot(positionMoveRotation); + Object newPositionMoveRotation = FastNMS.INSTANCE.constructor$PositionMoveRotation(position, deltaMovement, -yRot, Math.clamp(-xRot, -90.0F, 90.0F)); + return FastNMS.INSTANCE.constructor$ClientboundEntityPositionSyncPacket(entityId, newPositionMoveRotation, onGround); } - public static void modifyCustomTridentMove(Object packet) throws IllegalAccessException { - float xRot = MCUtils.unpackDegrees(Reflections.field$ClientboundMoveEntityPacket$xRot.getByte(packet)); - float yRot = MCUtils.unpackDegrees(Reflections.field$ClientboundMoveEntityPacket$yRot.getByte(packet)); - Reflections.field$ClientboundMoveEntityPacket$xRot.setByte(packet, MCUtils.packDegrees(Math.clamp(-xRot, -90.0F, 90.0F))); - Reflections.field$ClientboundMoveEntityPacket$yRot.setByte(packet, MCUtils.packDegrees(-yRot)); + public static Object buildCustomTridentMove(Object packet, int entityId) { + short xa = FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$xa(packet); + short ya = FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$ya(packet); + short za = FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$za(packet); + float xRot = MCUtils.unpackDegrees(FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$xRot(packet)); + float yRot = MCUtils.unpackDegrees(FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$yRot(packet)); + boolean onGround = FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$onGround(packet); + return FastNMS.INSTANCE.constructor$ClientboundMoveEntityPacket$PosRot( + entityId, xa, ya, za, + MCUtils.packDegrees(-yRot), MCUtils.packDegrees(MCUtils.clamp(-xRot, -90.0F, 90.0F)), + onGround + ); } public static List buildCustomTridentSetEntityDataPacket(NetWorkUser user, List packedItems, int 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 d71b22597..035a3e303 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java @@ -6632,130 +6632,4 @@ public class Reflections { ) ); - public static final Field field$ClientboundSetEntityDataPacket$id = requireNonNull( - ReflectionUtils.getDeclaredField( - clazz$ClientboundSetEntityDataPacket, int.class, 0 - ) - ); - - public static final Class clazz$PositionMoveRotation = - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.entity.PositionMoveRotation") - ); - - public static final Constructor constructor$PositionMoveRotation = Optional.ofNullable(clazz$PositionMoveRotation) - .map(ReflectionUtils::getTheOnlyConstructor) - .orElse(null); - - public static final Field field$ClientboundEntityPositionSyncPacket$values = Optional.ofNullable(clazz$ClientboundEntityPositionSyncPacket) - .map(it -> ReflectionUtils.getInstanceDeclaredField(it, clazz$PositionMoveRotation, 0)) - .orElse(null); - - public static final Field field$ClientboundEntityPositionSyncPacket$onGround = Optional.ofNullable(clazz$ClientboundEntityPositionSyncPacket) - .map(it -> ReflectionUtils.getInstanceDeclaredField(it, boolean.class, 0)) - .orElse(null); - - public static final Field field$PositionMoveRotation$position = Optional.ofNullable(clazz$PositionMoveRotation) - .map(it -> ReflectionUtils.getInstanceDeclaredField(it, clazz$Vec3, 0)) - .orElse(null); - - public static final Field field$PositionMoveRotation$deltaMovement = Optional.ofNullable(clazz$PositionMoveRotation) - .map(it -> ReflectionUtils.getInstanceDeclaredField(it, clazz$Vec3, 1)) - .orElse(null); - - public static final Field field$PositionMoveRotation$yRot = Optional.ofNullable(clazz$PositionMoveRotation) - .map(it -> ReflectionUtils.getInstanceDeclaredField(it, float.class, 0)) - .orElse(null); - - public static final Field field$PositionMoveRotation$xRot = Optional.ofNullable(clazz$PositionMoveRotation) - .map(it -> ReflectionUtils.getInstanceDeclaredField(it, float.class, 1)) - .orElse(null); - - public static final Constructor constructor$ClientboundEntityPositionSyncPacket = Optional.ofNullable(clazz$ClientboundEntityPositionSyncPacket) - .map(ReflectionUtils::getTheOnlyConstructor) - .orElse(null); - - public static final Field field$ClientboundAddEntityPacket$xRot = requireNonNull( - ReflectionUtils.getDeclaredField( - clazz$ClientboundAddEntityPacket, byte.class, 0 - ) - ); - - public static final Field field$ClientboundAddEntityPacket$yRot = requireNonNull( - ReflectionUtils.getDeclaredField( - clazz$ClientboundAddEntityPacket, byte.class, 1 - ) - ); - - public static final Field field$ClientboundMoveEntityPacket$xRot = requireNonNull( - ReflectionUtils.getDeclaredField( - clazz$ClientboundMoveEntityPacket, byte.class, 1 - ) - ); - - public static final Field field$ClientboundMoveEntityPacket$yRot = requireNonNull( - ReflectionUtils.getDeclaredField( - clazz$ClientboundMoveEntityPacket, byte.class, 0 - ) - ); - - public static final Class clazz$ServerEntity = requireNonNull( - BukkitReflectionUtils.findReobfOrMojmapClass( - "server.level.EntityTrackerEntry", - "server.level.ServerEntity" - ) - ); - - public static final Method method$ServerEntity$sendChanges = requireNonNull( - ReflectionUtils.getMethod( - clazz$ServerEntity, void.class, new String[]{ "sendChanges", "a" } - ) - ); - - public static final Class clazz$ChunkMap$TrackedEntity = requireNonNull( - BukkitReflectionUtils.findReobfOrMojmapClass( - "server.level.PlayerChunkMap$EntityTracker", - "server.level.ChunkMap$TrackedEntity" - ) - ); - - public static final Field field$Entity$trackedEntity = requireNonNull( - ReflectionUtils.getDeclaredField( - clazz$Entity, clazz$ChunkMap$TrackedEntity, 0 - ) - ); - - public static final Field field$ChunkMap$TrackedEntity$serverEntity = requireNonNull( - ReflectionUtils.getDeclaredField( - clazz$ChunkMap$TrackedEntity, clazz$ServerEntity, 0 - ) - ); - - public static final Field field$Entity$wasTouchingWater = requireNonNull( - ReflectionUtils.getDeclaredField( - clazz$Entity, VersionHelper.isOrAbove1_21_2() - ? new String[]{ "wasTouchingWater", "ag" } : VersionHelper.isOrAbove1_20_5() - ? new String[]{ "wasTouchingWater", "aj" } : VersionHelper.isOrAbove1_20_2() - ? new String[]{ "wasTouchingWater", "ai" } : new String[]{ "wasTouchingWater", "ah" } - ) - ); - - public static final Class clazz$AbstractArrow = requireNonNull( - BukkitReflectionUtils.findReobfOrMojmapClass( - "world.entity.projectile.EntityArrow", - "world.entity.projectile.AbstractArrow" - ) - ); - - // 1.20~1.21.1 - public static final Field field$AbstractArrow$inGround = - ReflectionUtils.getDeclaredField( - clazz$AbstractArrow, boolean.class, 0 - ); - - // 1.21.2+ - public static final Method method$AbstractArrow$isInGround = - ReflectionUtils.getMethod( - clazz$AbstractArrow, boolean.class, VersionHelper.isOrAbove1_21_5() ? new String[]{ "isInGround", "e" } : new String[]{ "isInGround", "l" } - ); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/CustomTrident.java b/core/src/main/java/net/momirealms/craftengine/core/entity/CustomTrident.java new file mode 100644 index 000000000..aed870c82 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/CustomTrident.java @@ -0,0 +1,8 @@ +package net.momirealms.craftengine.core.entity; + +import net.momirealms.craftengine.core.util.Key; +import org.joml.Quaternionf; +import org.joml.Vector3f; + +public record CustomTrident(Key customTridentItemId, Byte displayType, Vector3f translation, Quaternionf rotationLefts) { +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java index 59d8a06a4..d9968d902 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.item; +import net.momirealms.craftengine.core.entity.CustomTrident; import net.momirealms.craftengine.core.item.modifier.EquippableModifier; import net.momirealms.craftengine.core.item.modifier.ItemDataModifier; import net.momirealms.craftengine.core.pack.misc.EquipmentGeneration; @@ -9,6 +10,8 @@ import net.momirealms.craftengine.core.util.MiscUtils; import net.momirealms.craftengine.core.util.ResourceConfigUtils; import net.momirealms.craftengine.core.util.VersionHelper; import org.jetbrains.annotations.Nullable; +import org.joml.Quaternionf; +import org.joml.Vector3f; import java.util.*; import java.util.stream.Collectors; @@ -22,6 +25,7 @@ public class ItemSettings { List anvilRepairItems = List.of(); boolean renameable = true; boolean canPlaceRelatedVanillaBlock = false; + CustomTrident customTrident; private ItemSettings() {} @@ -50,6 +54,7 @@ public class ItemSettings { newSettings.anvilRepairItems = settings.anvilRepairItems; newSettings.renameable = settings.renameable; newSettings.canPlaceRelatedVanillaBlock = settings.canPlaceRelatedVanillaBlock; + newSettings.customTrident = settings.customTrident; return newSettings; } @@ -65,6 +70,10 @@ public class ItemSettings { return settings; } + public CustomTrident customTrident() { + return customTrident; + } + public boolean canPlaceRelatedVanillaBlock() { return canPlaceRelatedVanillaBlock; } @@ -109,6 +118,11 @@ public class ItemSettings { return this; } + public ItemSettings customTrident(CustomTrident customTrident) { + this.customTrident = customTrident; + return this; + } + public ItemSettings canPlaceRelatedVanillaBlock(boolean canPlaceRelatedVanillaBlock) { this.canPlaceRelatedVanillaBlock = canPlaceRelatedVanillaBlock; return this; @@ -193,6 +207,14 @@ public class ItemSettings { boolean bool = (boolean) value; return settings -> settings.canPlaceRelatedVanillaBlock(bool); })); + registerFactory("custom-trident", (value -> { + Map args = MiscUtils.castToMap(value, false); + Key customTridentItemId = Key.of(args.get("custom-trident-item").toString()); + Byte displayType = Byte.valueOf(args.get("display-type").toString()); + Vector3f translation = MiscUtils.getAsVector3f(args.get("translation"), "translation"); + Quaternionf rotationLefts = MiscUtils.getAsQuaternionf(args.get("rotation-left"), "rotation-left"); + return settings -> settings.customTrident(new CustomTrident(customTridentItemId, displayType, translation, rotationLefts)); + })); } private static void registerFactory(String id, ItemSettings.Modifier.Factory factory) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/MCUtils.java b/core/src/main/java/net/momirealms/craftengine/core/util/MCUtils.java index 86f2093ca..ed472a652 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/MCUtils.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/MCUtils.java @@ -197,4 +197,16 @@ public class MCUtils { public static float unpackDegrees(byte degrees) { return (float)(degrees * 360) / 256.0F; } + + public static int clamp(int value, int min, int max) { + return Math.min(Math.max(value, min), max); + } + + public static float clamp(float value, float min, float max) { + return value < min ? min : Math.min(value, max); + } + + public static double clamp(double value, double min, double max) { + return value < min ? min : Math.min(value, max); + } } diff --git a/gradle.properties b/gradle.properties index ccae7e353..9acb04c0c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -50,7 +50,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.65.15 +nms_helper_version=0.65.17 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.31.23