From e371f7951fc3a0f8146423e5bfc864345e96cb61 Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Tue, 15 Jul 2025 14:57:11 +0800 Subject: [PATCH 1/8] =?UTF-8?q?fix(bukkit):=20=E4=BF=AE=E5=A4=8D1.21.5+?= =?UTF-8?q?=E7=9A=84=E7=89=A9=E5=93=81=E6=89=8B=E6=84=9F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/item/BukkitItemManager.java | 12 ++- .../plugin/network/PacketConsumers.java | 76 ++++++++++++++----- .../reflection/minecraft/CoreReflections.java | 23 ++++++ .../reflection/minecraft/MRegistryOps.java | 4 + .../minecraft/NetworkReflections.java | 27 +++++++ gradle.properties | 2 +- 6 files changed, 124 insertions(+), 20 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java index a4c4c12e7..c7708e902 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java @@ -15,6 +15,7 @@ import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBuiltInRegistries; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistries; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistryOps; import net.momirealms.craftengine.bukkit.util.ItemStackUtils; import net.momirealms.craftengine.bukkit.util.KeyUtils; import net.momirealms.craftengine.core.entity.player.Player; @@ -39,6 +40,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.*; +import java.util.function.Function; public class BukkitItemManager extends AbstractItemManager { static { @@ -56,8 +58,10 @@ public class BukkitItemManager extends AbstractItemManager { private final Object bedrockItemHolder; private final Item emptyItem; private final UniqueIdItem emptyUniqueItem; + private final Function decoratedHashOpsGenerator; private Set lastRegisteredPatterns = Set.of(); + @SuppressWarnings("unchecked") public BukkitItemManager(BukkitCraftEngine plugin) { super(plugin); instance = this; @@ -68,13 +72,14 @@ public class BukkitItemManager extends AbstractItemManager { this.armorEventListener = new ArmorEventListener(); this.networkItemHandler = VersionHelper.isOrAbove1_20_5() ? new ModernNetworkItemHandler() : new LegacyNetworkItemHandler(); this.registerAllVanillaItems(); - this.bedrockItemHolder = FastNMS.INSTANCE.method$Registry$getHolderByResourceKey(MBuiltInRegistries.ITEM, FastNMS.INSTANCE.method$ResourceKey$create(MRegistries.ITEM, KeyUtils.toResourceLocation(Key.of("minecraft:bedrock")))).get();; + this.bedrockItemHolder = FastNMS.INSTANCE.method$Registry$getHolderByResourceKey(MBuiltInRegistries.ITEM, FastNMS.INSTANCE.method$ResourceKey$create(MRegistries.ITEM, KeyUtils.toResourceLocation(Key.of("minecraft:bedrock")))).get(); this.registerCustomTrimMaterial(); this.loadLastRegisteredPatterns(); ItemStack emptyStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(CoreReflections.instance$ItemStack$EMPTY); this.emptyItem = this.wrap(emptyStack); this.emptyUniqueItem = new UniqueIdItem<>(UniqueKey.AIR, this.emptyItem); + this.decoratedHashOpsGenerator = VersionHelper.isOrAbove1_21_5() ? (Function) FastNMS.INSTANCE.createDecoratedHashOpsGenerator(MRegistryOps.HASHCODE) : null; } @SuppressWarnings("unchecked") @@ -452,4 +457,9 @@ public class BukkitItemManager extends AbstractItemManager { } return this.emptyItem; } + + @Nullable("在 1.21.5+ 才有") + public Function decoratedHashOpsGenerator() { + return decoratedHashOpsGenerator; + } } 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 109b6bcd3..2bd8a2c27 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 @@ -2124,23 +2124,6 @@ public class PacketConsumers { FriendlyByteBuf buf = event.getBuffer(); Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf); ItemStack itemStack = FastNMS.INSTANCE.method$FriendlyByteBuf$readItem(friendlyBuf); - if (VersionHelper.isOrAbove1_21_5()) { - Item wrapped = BukkitItemManager.instance().wrap(itemStack); - if (!wrapped.isEmpty() && wrapped.isCustomItem()) { - Object containerMenu = FastNMS.INSTANCE.field$Player$containerMenu(serverPlayer.serverPlayer()); - if (containerMenu != null) { - ItemStack carried = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(FastNMS.INSTANCE.method$AbstractContainerMenu$getCarried(containerMenu)); - if (ItemStackUtils.isEmpty(carried)) { - event.setChanged(true); - buf.clear(); - buf.writeVarInt(event.packetID()); - Object newFriendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf); - FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, carried); - return; - } - } - } - } BukkitItemManager.instance().s2c(itemStack, serverPlayer).ifPresent((newItemStack) -> { event.setChanged(true); buf.clear(); @@ -2247,7 +2230,64 @@ public class PacketConsumers { public static final BiConsumer CONTAINER_CLICK_1_20 = (user, event) -> { try { - if (VersionHelper.isOrAbove1_21_5()) return; // 1.21.5+需要其他办法解决同步问题 + if (VersionHelper.isOrAbove1_21_5()) { + FriendlyByteBuf buf = event.getBuffer(); + boolean changed = false; + Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf); + Object inventory = FastNMS.INSTANCE.method$Player$getInventory(user.serverPlayer()); + int containerId = buf.readContainerId(); + int stateId = buf.readVarInt(); + short slotNum = buf.readShort(); + byte buttonNum = buf.readByte(); + int clickType = buf.readVarInt(); + int i = buf.readVarInt(); + Int2ObjectMap changedSlots = new Int2ObjectOpenHashMap<>(i); + for (int j = 0; j < i; ++j) { + int k = buf.readShort(); + Object hashedStack = FastNMS.INSTANCE.method$StreamDecoder$decode(NetworkReflections.instance$HashedStack$STREAM_CODEC, friendlyBuf); + Object serverSideItemStack = FastNMS.INSTANCE.method$Container$getItem(inventory, k); + Optional optional = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(serverSideItemStack), ((net.momirealms.craftengine.core.entity.player.Player) user)); + if (optional.isPresent()) { + Object clientSideItemStack = FastNMS.INSTANCE.field$CraftItemStack$handle(optional.get()); + boolean isSync = FastNMS.INSTANCE.method$HashedStack$matches(hashedStack, clientSideItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator()); + if (isSync) { + changed = true; + hashedStack = FastNMS.INSTANCE.method$HashedStack$create(clientSideItemStack, null); + } + } + changedSlots.put(k, hashedStack); + } + Object carriedHashedStack = FastNMS.INSTANCE.method$StreamDecoder$decode(NetworkReflections.instance$HashedStack$STREAM_CODEC, friendlyBuf); + Object containerMenu = FastNMS.INSTANCE.field$Player$containerMenu(user.serverPlayer()); + Object serverSideCarriedItemStack = FastNMS.INSTANCE.method$AbstractContainerMenu$getCarried(containerMenu); + Optional optional = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(serverSideCarriedItemStack), ((net.momirealms.craftengine.core.entity.player.Player) user)); + if (optional.isPresent()) { + Object clientSideCarriedItemStack = FastNMS.INSTANCE.field$CraftItemStack$handle(optional.get()); + boolean isSync = FastNMS.INSTANCE.method$HashedStack$matches(carriedHashedStack, clientSideCarriedItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator()); + if (isSync) { + changed = true; + carriedHashedStack = FastNMS.INSTANCE.method$HashedStack$create(clientSideCarriedItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator()); + } + } + if (changed) { + event.setChanged(true); + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeContainerId(containerId); + buf.writeVarInt(stateId); + buf.writeShort(slotNum); + buf.writeByte(buttonNum); + buf.writeVarInt(clickType); + buf.writeVarInt(changedSlots.size()); + Object newFriendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf); + changedSlots.forEach((k, v) -> { + buf.writeShort(k); + FastNMS.INSTANCE.method$StreamEncoder$encode(NetworkReflections.instance$HashedStack$STREAM_CODEC, newFriendlyBuf, v); + }); + FastNMS.INSTANCE.method$StreamEncoder$encode(NetworkReflections.instance$HashedStack$STREAM_CODEC, newFriendlyBuf, carriedHashedStack); + } + return; + } FriendlyByteBuf buf = event.getBuffer(); boolean changed = false; Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java index e99d6d8b6..b8e41241c 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java @@ -3850,4 +3850,27 @@ public final class CoreReflections { CoreReflections.clazz$BlockHitResult, CoreReflections.clazz$Vec3, CoreReflections.clazz$Direction, CoreReflections.clazz$BlockPos, boolean.class ) ); + + public static final Class clazz$HashOps = MiscUtils.requireNonNullIf( + ReflectionUtils.getClazz(BukkitReflectionUtils.assembleMCClass("util.HashOps")), + VersionHelper.isOrAbove1_21_5() + ); + + public static final Field field$HashOps$CRC32C_INSTANCE = Optional.ofNullable(clazz$HashOps) + .map(it -> ReflectionUtils.getDeclaredField(it, it, 0)) + .orElse(null); + + public static final Object instance$HashOps$CRC32C_INSTANCE; + + static { + try { + if (VersionHelper.isOrAbove1_21_5()) { + instance$HashOps$CRC32C_INSTANCE = field$HashOps$CRC32C_INSTANCE.get(null); + } else { + instance$HashOps$CRC32C_INSTANCE = null; + } + } catch (ReflectiveOperationException e) { + throw new ReflectionInitException("Failed to initialize HashOps", e); + } + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MRegistryOps.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MRegistryOps.java index dd90cb582..f304ef155 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MRegistryOps.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MRegistryOps.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.bukkit.plugin.reflection.minecraft; +import com.google.common.hash.HashCode; import com.google.gson.JsonElement; import com.mojang.serialization.DynamicOps; import com.mojang.serialization.JsonOps; @@ -12,6 +13,7 @@ import net.momirealms.sparrow.nbt.Tag; import net.momirealms.sparrow.nbt.codec.LegacyJavaOps; import net.momirealms.sparrow.nbt.codec.LegacyNBTOps; import net.momirealms.sparrow.nbt.codec.NBTOps; +import org.jetbrains.annotations.Nullable; import static java.util.Objects.requireNonNull; @@ -21,6 +23,7 @@ public final class MRegistryOps { public static final DynamicOps SPARROW_NBT; public static final DynamicOps JAVA; public static final DynamicOps JSON; + public static final @Nullable("仅在 1.21.5+ 有") DynamicOps HASHCODE; // 1.20.5+ public static final Class clazz$JavaOps = ReflectionUtils.getClazz("com.mojang.serialization.JavaOps"); @@ -47,6 +50,7 @@ public final class MRegistryOps { NBT = (DynamicOps) CoreReflections.method$RegistryOps$create.invoke(null, ReflectionUtils.getDeclaredField(clazz$NbtOps, clazz$NbtOps, 0).get(null), FastNMS.INSTANCE.registryAccess()); JSON = (DynamicOps) CoreReflections.method$RegistryOps$create.invoke(null, JsonOps.INSTANCE, FastNMS.INSTANCE.registryAccess()); SPARROW_NBT = (DynamicOps) CoreReflections.method$RegistryOps$create.invoke(null, VersionHelper.isOrAbove1_20_5() ? NBTOps.INSTANCE : LegacyNBTOps.INSTANCE, FastNMS.INSTANCE.registryAccess()); + HASHCODE = VersionHelper.isOrAbove1_21_5() ? (DynamicOps) CoreReflections.method$RegistryOps$create.invoke(null, CoreReflections.instance$HashOps$CRC32C_INSTANCE, FastNMS.INSTANCE.registryAccess()) : null; } catch (ReflectiveOperationException e) { throw new ReflectionInitException("Failed to init DynamicOps", e); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/NetworkReflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/NetworkReflections.java index 9b5377f07..6c1d427a9 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/NetworkReflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/NetworkReflections.java @@ -1594,4 +1594,31 @@ public final class NetworkReflections { List.of("network.protocol.common.ClientboundUpdateTagsPacket", "network.protocol.game.ClientboundUpdateTagsPacket") ) ); + + // 1.21.5+ + public static final Class clazz$HashedStack = MiscUtils.requireNonNullIf( + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleMCClass("network.HashedStack") + ), + VersionHelper.isOrAbove1_21_5() + ); + + // 1.21.5+ + public static final Field field$HashedStack$STREAM_CODEC = Optional.ofNullable(clazz$HashedStack) + .map(it -> ReflectionUtils.getDeclaredField(it, clazz$StreamCodec, 0)) + .orElse(null); + + public static final Object instance$HashedStack$STREAM_CODEC; + + static { + try { + if (VersionHelper.isOrAbove1_21_5()) { + instance$HashedStack$STREAM_CODEC = field$HashedStack$STREAM_CODEC.get(null); + } else { + instance$HashedStack$STREAM_CODEC = null; + } + } catch (ReflectiveOperationException e) { + throw new ReflectionInitException("Failed to initialize HashedStack$STREAM_CODEC", e); + } + } } diff --git a/gradle.properties b/gradle.properties index 6c5b9b256..af7ef18be 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.18 -nms_helper_version=1.0.34 +nms_helper_version=1.0.35 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.31.23 From aa6f4f100ec8c9bb3c747a0079823a0a8e654108 Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Tue, 15 Jul 2025 15:02:52 +0800 Subject: [PATCH 2/8] =?UTF-8?q?refactor(network):=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../craftengine/bukkit/plugin/network/BukkitNetworkManager.java | 2 +- .../craftengine/bukkit/plugin/network/PacketConsumers.java | 2 +- 2 files changed, 2 insertions(+), 2 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 be7cc4e4f..eedb8f624 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 @@ -188,7 +188,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes registerS2CByteBufPacketConsumer(PacketConsumers.SET_EQUIPMENT, this.packetIds.clientboundSetEquipmentPacket()); registerS2CByteBufPacketConsumer(PacketConsumers.SET_PLAYER_INVENTORY_1_21_2, this.packetIds.clientboundSetPlayerInventoryPacket()); registerC2SByteBufPacketConsumer(PacketConsumers.SET_CREATIVE_MODE_SLOT, this.packetIds.serverboundSetCreativeModeSlotPacket()); - registerC2SByteBufPacketConsumer(PacketConsumers.CONTAINER_CLICK_1_20, this.packetIds.serverboundContainerClickPacket()); + registerC2SByteBufPacketConsumer(PacketConsumers.CONTAINER_CLICK, this.packetIds.serverboundContainerClickPacket()); registerC2SByteBufPacketConsumer(PacketConsumers.INTERACT_ENTITY, this.packetIds.serverboundInteractPacket()); } 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 2bd8a2c27..02dd5c16e 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 @@ -2228,7 +2228,7 @@ public class PacketConsumers { } }; - public static final BiConsumer CONTAINER_CLICK_1_20 = (user, event) -> { + public static final BiConsumer CONTAINER_CLICK = (user, event) -> { try { if (VersionHelper.isOrAbove1_21_5()) { FriendlyByteBuf buf = event.getBuffer(); From 04588340dafec19978497c9765cf1585133743b9 Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Tue, 15 Jul 2025 15:21:10 +0800 Subject: [PATCH 3/8] =?UTF-8?q?fix(bukkit):=20=E4=BF=AE=E5=A4=8D=E7=96=8F?= =?UTF-8?q?=E5=BF=BD=E5=86=99=E9=94=99=E7=9A=84=E5=87=A0=E4=B8=AA=E5=9C=B0?= =?UTF-8?q?=E6=96=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/plugin/network/PacketConsumers.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 02dd5c16e..519082a7b 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 @@ -2246,13 +2246,13 @@ public class PacketConsumers { int k = buf.readShort(); Object hashedStack = FastNMS.INSTANCE.method$StreamDecoder$decode(NetworkReflections.instance$HashedStack$STREAM_CODEC, friendlyBuf); Object serverSideItemStack = FastNMS.INSTANCE.method$Container$getItem(inventory, k); - Optional optional = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(serverSideItemStack), ((net.momirealms.craftengine.core.entity.player.Player) user)); + Optional optional = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(serverSideItemStack).clone(), ((net.momirealms.craftengine.core.entity.player.Player) user)); if (optional.isPresent()) { Object clientSideItemStack = FastNMS.INSTANCE.field$CraftItemStack$handle(optional.get()); boolean isSync = FastNMS.INSTANCE.method$HashedStack$matches(hashedStack, clientSideItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator()); if (isSync) { changed = true; - hashedStack = FastNMS.INSTANCE.method$HashedStack$create(clientSideItemStack, null); + hashedStack = FastNMS.INSTANCE.method$HashedStack$create(serverSideItemStack, null); } } changedSlots.put(k, hashedStack); @@ -2260,13 +2260,13 @@ public class PacketConsumers { Object carriedHashedStack = FastNMS.INSTANCE.method$StreamDecoder$decode(NetworkReflections.instance$HashedStack$STREAM_CODEC, friendlyBuf); Object containerMenu = FastNMS.INSTANCE.field$Player$containerMenu(user.serverPlayer()); Object serverSideCarriedItemStack = FastNMS.INSTANCE.method$AbstractContainerMenu$getCarried(containerMenu); - Optional optional = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(serverSideCarriedItemStack), ((net.momirealms.craftengine.core.entity.player.Player) user)); + Optional optional = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(serverSideCarriedItemStack).clone(), ((net.momirealms.craftengine.core.entity.player.Player) user)); if (optional.isPresent()) { Object clientSideCarriedItemStack = FastNMS.INSTANCE.field$CraftItemStack$handle(optional.get()); boolean isSync = FastNMS.INSTANCE.method$HashedStack$matches(carriedHashedStack, clientSideCarriedItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator()); if (isSync) { changed = true; - carriedHashedStack = FastNMS.INSTANCE.method$HashedStack$create(clientSideCarriedItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator()); + carriedHashedStack = FastNMS.INSTANCE.method$HashedStack$create(serverSideCarriedItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator()); } } if (changed) { From 049145d6a4466296af7309f4de3893a05862459f Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Tue, 15 Jul 2025 15:23:19 +0800 Subject: [PATCH 4/8] =?UTF-8?q?fix(bukkit):=20=E4=BF=AE=E5=A4=8D=E7=96=8F?= =?UTF-8?q?=E5=BF=BD=E5=86=99=E9=94=99=E7=9A=84=E5=87=A0=E4=B8=AA=E5=9C=B0?= =?UTF-8?q?=E6=96=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../craftengine/bukkit/plugin/network/PacketConsumers.java | 2 +- 1 file changed, 1 insertion(+), 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 519082a7b..a32c1d2b5 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 @@ -2252,7 +2252,7 @@ public class PacketConsumers { boolean isSync = FastNMS.INSTANCE.method$HashedStack$matches(hashedStack, clientSideItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator()); if (isSync) { changed = true; - hashedStack = FastNMS.INSTANCE.method$HashedStack$create(serverSideItemStack, null); + hashedStack = FastNMS.INSTANCE.method$HashedStack$create(serverSideItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator()); } } changedSlots.put(k, hashedStack); From e800eb4fc2f756fa0884b851a7b08a136e3ccf7c Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Thu, 17 Jul 2025 09:01:59 +0800 Subject: [PATCH 5/8] =?UTF-8?q?refactor(network):=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=B3=A8=E8=A7=A3=E5=B9=B6=E5=88=87=E5=89=B2CONTAINER=5FCLICK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/item/BukkitItemManager.java | 2 +- .../plugin/network/BukkitNetworkManager.java | 2 +- .../plugin/network/PacketConsumers.java | 110 +++++++++--------- .../reflection/minecraft/MRegistryOps.java | 2 +- 4 files changed, 60 insertions(+), 56 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java index c7708e902..733642857 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java @@ -458,7 +458,7 @@ public class BukkitItemManager extends AbstractItemManager { return this.emptyItem; } - @Nullable("在 1.21.5+ 才有") + @Nullable // 1.21.5+ public Function decoratedHashOpsGenerator() { return decoratedHashOpsGenerator; } 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 eedb8f624..bdc6aa116 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 @@ -188,7 +188,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes registerS2CByteBufPacketConsumer(PacketConsumers.SET_EQUIPMENT, this.packetIds.clientboundSetEquipmentPacket()); registerS2CByteBufPacketConsumer(PacketConsumers.SET_PLAYER_INVENTORY_1_21_2, this.packetIds.clientboundSetPlayerInventoryPacket()); registerC2SByteBufPacketConsumer(PacketConsumers.SET_CREATIVE_MODE_SLOT, this.packetIds.serverboundSetCreativeModeSlotPacket()); - registerC2SByteBufPacketConsumer(PacketConsumers.CONTAINER_CLICK, this.packetIds.serverboundContainerClickPacket()); + registerC2SByteBufPacketConsumer(VersionHelper.isOrAbove1_21_5() ? PacketConsumers.CONTAINER_CLICK_1_21_5 : PacketConsumers.CONTAINER_CLICK_1_20, this.packetIds.serverboundContainerClickPacket()); registerC2SByteBufPacketConsumer(PacketConsumers.INTERACT_ENTITY, this.packetIds.serverboundInteractPacket()); } 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 a32c1d2b5..21685624a 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 @@ -2228,66 +2228,70 @@ public class PacketConsumers { } }; - public static final BiConsumer CONTAINER_CLICK = (user, event) -> { + public static final BiConsumer CONTAINER_CLICK_1_21_5 = (user, event) -> { try { - if (VersionHelper.isOrAbove1_21_5()) { - FriendlyByteBuf buf = event.getBuffer(); - boolean changed = false; - Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf); - Object inventory = FastNMS.INSTANCE.method$Player$getInventory(user.serverPlayer()); - int containerId = buf.readContainerId(); - int stateId = buf.readVarInt(); - short slotNum = buf.readShort(); - byte buttonNum = buf.readByte(); - int clickType = buf.readVarInt(); - int i = buf.readVarInt(); - Int2ObjectMap changedSlots = new Int2ObjectOpenHashMap<>(i); - for (int j = 0; j < i; ++j) { - int k = buf.readShort(); - Object hashedStack = FastNMS.INSTANCE.method$StreamDecoder$decode(NetworkReflections.instance$HashedStack$STREAM_CODEC, friendlyBuf); - Object serverSideItemStack = FastNMS.INSTANCE.method$Container$getItem(inventory, k); - Optional optional = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(serverSideItemStack).clone(), ((net.momirealms.craftengine.core.entity.player.Player) user)); - if (optional.isPresent()) { - Object clientSideItemStack = FastNMS.INSTANCE.field$CraftItemStack$handle(optional.get()); - boolean isSync = FastNMS.INSTANCE.method$HashedStack$matches(hashedStack, clientSideItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator()); - if (isSync) { - changed = true; - hashedStack = FastNMS.INSTANCE.method$HashedStack$create(serverSideItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator()); - } - } - changedSlots.put(k, hashedStack); - } - Object carriedHashedStack = FastNMS.INSTANCE.method$StreamDecoder$decode(NetworkReflections.instance$HashedStack$STREAM_CODEC, friendlyBuf); - Object containerMenu = FastNMS.INSTANCE.field$Player$containerMenu(user.serverPlayer()); - Object serverSideCarriedItemStack = FastNMS.INSTANCE.method$AbstractContainerMenu$getCarried(containerMenu); - Optional optional = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(serverSideCarriedItemStack).clone(), ((net.momirealms.craftengine.core.entity.player.Player) user)); + FriendlyByteBuf buf = event.getBuffer(); + boolean changed = false; + Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf); + Object inventory = FastNMS.INSTANCE.method$Player$getInventory(user.serverPlayer()); + int containerId = buf.readContainerId(); + int stateId = buf.readVarInt(); + short slotNum = buf.readShort(); + byte buttonNum = buf.readByte(); + int clickType = buf.readVarInt(); + int i = buf.readVarInt(); + Int2ObjectMap changedSlots = new Int2ObjectOpenHashMap<>(i); + for (int j = 0; j < i; ++j) { + int k = buf.readShort(); + Object hashedStack = FastNMS.INSTANCE.method$StreamDecoder$decode(NetworkReflections.instance$HashedStack$STREAM_CODEC, friendlyBuf); + Object serverSideItemStack = FastNMS.INSTANCE.method$Container$getItem(inventory, k); + Optional optional = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(serverSideItemStack).clone(), ((net.momirealms.craftengine.core.entity.player.Player) user)); if (optional.isPresent()) { - Object clientSideCarriedItemStack = FastNMS.INSTANCE.field$CraftItemStack$handle(optional.get()); - boolean isSync = FastNMS.INSTANCE.method$HashedStack$matches(carriedHashedStack, clientSideCarriedItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator()); + Object clientSideItemStack = FastNMS.INSTANCE.field$CraftItemStack$handle(optional.get()); + boolean isSync = FastNMS.INSTANCE.method$HashedStack$matches(hashedStack, clientSideItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator()); if (isSync) { changed = true; - carriedHashedStack = FastNMS.INSTANCE.method$HashedStack$create(serverSideCarriedItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator()); + hashedStack = FastNMS.INSTANCE.method$HashedStack$create(serverSideItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator()); } } - if (changed) { - event.setChanged(true); - buf.clear(); - buf.writeVarInt(event.packetID()); - buf.writeContainerId(containerId); - buf.writeVarInt(stateId); - buf.writeShort(slotNum); - buf.writeByte(buttonNum); - buf.writeVarInt(clickType); - buf.writeVarInt(changedSlots.size()); - Object newFriendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf); - changedSlots.forEach((k, v) -> { - buf.writeShort(k); - FastNMS.INSTANCE.method$StreamEncoder$encode(NetworkReflections.instance$HashedStack$STREAM_CODEC, newFriendlyBuf, v); - }); - FastNMS.INSTANCE.method$StreamEncoder$encode(NetworkReflections.instance$HashedStack$STREAM_CODEC, newFriendlyBuf, carriedHashedStack); - } - return; + changedSlots.put(k, hashedStack); } + Object carriedHashedStack = FastNMS.INSTANCE.method$StreamDecoder$decode(NetworkReflections.instance$HashedStack$STREAM_CODEC, friendlyBuf); + Object containerMenu = FastNMS.INSTANCE.field$Player$containerMenu(user.serverPlayer()); + Object serverSideCarriedItemStack = FastNMS.INSTANCE.method$AbstractContainerMenu$getCarried(containerMenu); + Optional optional = BukkitItemManager.instance().s2c(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(serverSideCarriedItemStack).clone(), ((net.momirealms.craftengine.core.entity.player.Player) user)); + if (optional.isPresent()) { + Object clientSideCarriedItemStack = FastNMS.INSTANCE.field$CraftItemStack$handle(optional.get()); + boolean isSync = FastNMS.INSTANCE.method$HashedStack$matches(carriedHashedStack, clientSideCarriedItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator()); + if (isSync) { + changed = true; + carriedHashedStack = FastNMS.INSTANCE.method$HashedStack$create(serverSideCarriedItemStack, BukkitItemManager.instance().decoratedHashOpsGenerator()); + } + } + if (changed) { + event.setChanged(true); + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeContainerId(containerId); + buf.writeVarInt(stateId); + buf.writeShort(slotNum); + buf.writeByte(buttonNum); + buf.writeVarInt(clickType); + buf.writeVarInt(changedSlots.size()); + Object newFriendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf); + changedSlots.forEach((k, v) -> { + buf.writeShort(k); + FastNMS.INSTANCE.method$StreamEncoder$encode(NetworkReflections.instance$HashedStack$STREAM_CODEC, newFriendlyBuf, v); + }); + FastNMS.INSTANCE.method$StreamEncoder$encode(NetworkReflections.instance$HashedStack$STREAM_CODEC, newFriendlyBuf, carriedHashedStack); + } + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ServerboundContainerClickPacket", e); + } + }; + + public static final BiConsumer CONTAINER_CLICK_1_20 = (user, event) -> { + try { FriendlyByteBuf buf = event.getBuffer(); boolean changed = false; Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MRegistryOps.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MRegistryOps.java index f304ef155..ae470d777 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MRegistryOps.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MRegistryOps.java @@ -23,7 +23,7 @@ public final class MRegistryOps { public static final DynamicOps SPARROW_NBT; public static final DynamicOps JAVA; public static final DynamicOps JSON; - public static final @Nullable("仅在 1.21.5+ 有") DynamicOps HASHCODE; + public static final @Nullable DynamicOps HASHCODE; // 1.21.5+ // 1.20.5+ public static final Class clazz$JavaOps = ReflectionUtils.getClazz("com.mojang.serialization.JavaOps"); From 5e3115c08c76795b3716b53f7aa0f783157ca786 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Thu, 17 Jul 2025 16:02:50 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E9=85=8D=E6=96=B9=E5=90=8E=E5=A4=84?= =?UTF-8?q?=E7=90=86=E5=99=A8=E7=9A=84=E5=87=86=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../worldedit/FastAsyncWorldEditDelegate.java | 7 +- .../bukkit/item/BukkitCustomItem.java | 6 +- .../bukkit/item/BukkitItemManager.java | 8 +-- .../bukkit/item/CloneableConstantItem.java | 14 ++-- .../item/recipe/BukkitRecipeManager.java | 10 +-- .../craftengine/core/entity/Entity.java | 2 - .../core/item/AbstractItemManager.java | 5 ++ .../craftengine/core/item/BuildableItem.java | 10 +++ .../craftengine/core/item/CustomItem.java | 7 -- .../craftengine/core/item/ItemManager.java | 2 + .../item/recipe/AbstractGroupedRecipe.java | 6 -- .../core/item/recipe/CustomBrewingRecipe.java | 5 -- .../core/item/recipe/CustomRecipeResult.java | 67 ++++++++++++++++++- .../recipe/CustomSmithingTransformRecipe.java | 1 + .../core/item/recipe/FixedResultRecipe.java | 6 ++ .../core/item/recipe/RecipeFactory.java | 3 +- .../core/registry/BuiltInRegistries.java | 2 + .../craftengine/core/registry/Registries.java | 3 +- 18 files changed, 118 insertions(+), 46 deletions(-) diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/FastAsyncWorldEditDelegate.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/FastAsyncWorldEditDelegate.java index 2263c7f25..b03240f25 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/FastAsyncWorldEditDelegate.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/FastAsyncWorldEditDelegate.java @@ -46,14 +46,12 @@ import static java.util.Objects.requireNonNull; public class FastAsyncWorldEditDelegate extends AbstractDelegateExtent { private static int[] ordinalToIbdID; - private final Extent extent; private final Set chunksToSave; private final CEWorld ceWorld; private final Set brokenChunks = Collections.synchronizedSet(new HashSet<>()); protected FastAsyncWorldEditDelegate(EditSessionEvent event, Extent extent) { super(extent); - this.extent = extent; this.chunksToSave = new HashSet<>(); World weWorld = event.getWorld(); org.bukkit.World world = Bukkit.getWorld(requireNonNull(weWorld).getName()); @@ -77,8 +75,9 @@ public class FastAsyncWorldEditDelegate extends AbstractDelegateExtent { public void onEditSessionEvent(EditSessionEvent event) { World weWorld = event.getWorld(); if (weWorld == null) return; + Extent currentExtent = event.getExtent(); if (event.getStage() == EditSession.Stage.BEFORE_CHANGE) { - event.setExtent(new FastAsyncWorldEditDelegate(event, event.getExtent())); + event.setExtent(new FastAsyncWorldEditDelegate(event, currentExtent)); } } }); @@ -138,7 +137,7 @@ public class FastAsyncWorldEditDelegate extends AbstractDelegateExtent { @Override public > boolean setBlock(int x, int y, int z, T block) { - boolean result = extent.setBlock(x, y, z, block); + boolean result = super.setBlock(x, y, z, block); if (result) { Mask mask = getMask(); if (mask != null && !mask.test(BlockVector3.at(x, y, z))) return true; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitCustomItem.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitCustomItem.java index 40954b670..4f8e68a97 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitCustomItem.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitCustomItem.java @@ -42,13 +42,13 @@ public class BukkitCustomItem extends AbstractCustomItem { } @Override - public Item buildItem(ItemBuildContext context) { - ItemStack item = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(FastNMS.INSTANCE.constructor$ItemStack(this.item, 1)); + public Item buildItem(ItemBuildContext context, int count) { + ItemStack item = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(FastNMS.INSTANCE.constructor$ItemStack(this.item, count)); Item wrapped = BukkitCraftEngine.instance().itemManager().wrap(item); for (ItemDataModifier modifier : dataModifiers()) { modifier.apply(wrapped, context); } - return BukkitCraftEngine.instance().itemManager().wrap(wrapped.getItem()); + return wrapped; } public Object clientItem() { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java index 733642857..64e8735e5 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java @@ -29,8 +29,6 @@ import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigExce import net.momirealms.craftengine.core.plugin.logger.Debugger; import net.momirealms.craftengine.core.util.*; import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.Registry; import org.bukkit.event.HandlerList; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; @@ -165,11 +163,11 @@ public class BukkitItemManager extends AbstractItemManager { @Override public Optional> getVanillaItem(Key key) { - Material material = Registry.MATERIAL.get(KeyUtils.toNamespacedKey(key)); - if (material == null) { + ItemStack vanilla = createVanillaItemStack(key); + if (vanilla == null) { return Optional.empty(); } - return Optional.of(new CloneableConstantItem(key, new ItemStack(material))); + return Optional.of(new CloneableConstantItem(key, this.wrap(vanilla))); } @Override diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/CloneableConstantItem.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/CloneableConstantItem.java index 6eb6eb61d..13fb185c6 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/CloneableConstantItem.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/CloneableConstantItem.java @@ -1,15 +1,16 @@ package net.momirealms.craftengine.bukkit.item; import net.momirealms.craftengine.core.item.BuildableItem; +import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; import net.momirealms.craftengine.core.util.Key; import org.bukkit.inventory.ItemStack; public class CloneableConstantItem implements BuildableItem { - private final ItemStack item; + private final Item item; private final Key id; - public CloneableConstantItem(Key id, ItemStack item) { + public CloneableConstantItem(Key id, Item item) { this.item = item; this.id = id; } @@ -19,10 +20,13 @@ public class CloneableConstantItem implements BuildableItem { return this.id; } + @Override + public Item buildItem(ItemBuildContext context, int count) { + return this.item.copyWithCount(count); + } + @Override public ItemStack buildItemStack(ItemBuildContext context, int count) { - ItemStack itemStack = this.item.clone(); - itemStack.setAmount(count); - return itemStack; + return this.item.copyWithCount(count).getItem(); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java index 975c2a42d..953f220fe 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/BukkitRecipeManager.java @@ -561,7 +561,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager { } CustomStoneCuttingRecipe ceRecipe = new CustomStoneCuttingRecipe<>( id, recipe.group(), Ingredient.of(holders), - new CustomRecipeResult<>(new CloneableConstantItem(recipe.result().isCustom() ? Key.of("!internal:custom") : Key.of(recipe.result().id()), result), recipe.result().count()) + new CustomRecipeResult<>(new CloneableConstantItem(recipe.result().isCustom() ? Key.of("!internal:custom") : Key.of(recipe.result().id()), BukkitItemManager.instance().wrap(result)), recipe.result().count(), null) ); this.registerInternalRecipe(id, ceRecipe); } @@ -590,7 +590,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager { } CustomShapelessRecipe ceRecipe = new CustomShapelessRecipe<>( id, recipe.category(), recipe.group(), ingredientList, - new CustomRecipeResult<>(new CloneableConstantItem(recipe.result().isCustom() ? Key.of("!internal:custom") : Key.of(recipe.result().id()), result), recipe.result().count()) + new CustomRecipeResult<>(new CloneableConstantItem(recipe.result().isCustom() ? Key.of("!internal:custom") : Key.of(recipe.result().id()), BukkitItemManager.instance().wrap(result)), recipe.result().count(), null) ); if (hasCustomItemInTag) { Runnable converted = findNMSRecipeConvertor(ceRecipe).convert(id, ceRecipe); @@ -627,7 +627,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager { CustomShapedRecipe ceRecipe = new CustomShapedRecipe<>( id, recipe.category(), recipe.group(), new CustomShapedRecipe.Pattern<>(recipe.pattern(), ingredients), - new CustomRecipeResult<>(new CloneableConstantItem(recipe.result().isCustom() ? Key.of("!internal:custom") : Key.of(recipe.result().id()), result), recipe.result().count()) + new CustomRecipeResult<>(new CloneableConstantItem(recipe.result().isCustom() ? Key.of("!internal:custom") : Key.of(recipe.result().id()), BukkitItemManager.instance().wrap(result)), recipe.result().count(), null) ); if (hasCustomItemInTag) { Runnable converted = findNMSRecipeConvertor(ceRecipe).convert(id, ceRecipe); @@ -651,7 +651,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager { id, recipe.category(), recipe.group(), Ingredient.of(holders), recipe.cookingTime(), recipe.experience(), - new CustomRecipeResult<>(new CloneableConstantItem(recipe.result().isCustom() ? Key.of("!internal:custom") : Key.of(recipe.result().id()), result), recipe.result().count()) + new CustomRecipeResult<>(new CloneableConstantItem(recipe.result().isCustom() ? Key.of("!internal:custom") : Key.of(recipe.result().id()), BukkitItemManager.instance().wrap(result)), recipe.result().count(), null) ); if (hasCustomItemInTag) { Runnable converted = findNMSRecipeConvertor(ceRecipe).convert(id, ceRecipe); @@ -680,7 +680,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager { baseHolders.isEmpty() ? null : Ingredient.of(baseHolders), templateHolders.isEmpty() ? null : Ingredient.of(templateHolders), additionHolders.isEmpty() ? null : Ingredient.of(additionHolders), - new CustomRecipeResult<>(new CloneableConstantItem(recipe.result().isCustom() ? Key.of("!internal:custom") : Key.of(recipe.result().id()), result), recipe.result().count()), + new CustomRecipeResult<>(new CloneableConstantItem(recipe.result().isCustom() ? Key.of("!internal:custom") : Key.of(recipe.result().id()), BukkitItemManager.instance().wrap(result)), recipe.result().count(), null), true, List.of() ); diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/Entity.java b/core/src/main/java/net/momirealms/craftengine/core/entity/Entity.java index 8a43adf97..aac181c4b 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/Entity.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/Entity.java @@ -2,10 +2,8 @@ package net.momirealms.craftengine.core.entity; import net.momirealms.craftengine.core.util.Direction; import net.momirealms.craftengine.core.util.Key; -import net.momirealms.craftengine.core.util.MCUtils; import net.momirealms.craftengine.core.world.World; import net.momirealms.craftengine.core.world.WorldPosition; -import net.momirealms.sparrow.nbt.util.MathUtil; import java.util.UUID; diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java index 02b362da3..6b75dc648 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java @@ -93,6 +93,11 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl } } + @Override + public Function> getDataType(String key) { + return this.dataFunctions.get(key); + } + @Override public ConfigParser[] parsers() { return new ConfigParser[]{this.itemParser, this.equipmentParser}; diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/BuildableItem.java b/core/src/main/java/net/momirealms/craftengine/core/item/BuildableItem.java index ed2e23317..1d3db94da 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/BuildableItem.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/BuildableItem.java @@ -8,6 +8,16 @@ public interface BuildableItem { Key id(); + Item buildItem(ItemBuildContext context, int count); + + default Item buildItem(Player player) { + return buildItem(ItemBuildContext.of(player)); + } + + default Item buildItem(ItemBuildContext context) { + return buildItem(context, 1); + } + I buildItemStack(ItemBuildContext context, int count); default I buildItemStack(ItemBuildContext context) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/CustomItem.java b/core/src/main/java/net/momirealms/craftengine/core/item/CustomItem.java index b1f37784b..2ab666cf9 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/CustomItem.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/CustomItem.java @@ -1,6 +1,5 @@ package net.momirealms.craftengine.core.item; -import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.item.behavior.ItemBehavior; import net.momirealms.craftengine.core.item.modifier.ItemDataModifier; import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext; @@ -35,12 +34,6 @@ public interface CustomItem extends BuildableItem { return settings().tags().contains(tag); } - default Item buildItem(Player player) { - return buildItem(ItemBuildContext.of(player)); - } - - Item buildItem(ItemBuildContext context); - void execute(PlayerOptionalContext context, EventTrigger trigger); @NotNull diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java index 9505da8f1..d88e2d5d3 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java @@ -24,6 +24,8 @@ public interface ItemManager extends Manageable, ModelGenerator { void registerDataType(Function> factory, String... alias); + Function> getDataType(String key); + Map equipments(); ConfigParser[] parsers(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractGroupedRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractGroupedRecipe.java index 69ec59426..9b71c93ce 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractGroupedRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractGroupedRecipe.java @@ -1,7 +1,6 @@ package net.momirealms.craftengine.core.item.recipe; import net.momirealms.craftengine.core.item.ItemBuildContext; -import net.momirealms.craftengine.core.item.recipe.input.RecipeInput; import net.momirealms.craftengine.core.util.Key; import org.jetbrains.annotations.Nullable; @@ -16,11 +15,6 @@ public abstract class AbstractGroupedRecipe implements FixedResultRecipe { this.result = result; } - @Override - public T assemble(RecipeInput input, ItemBuildContext context) { - return this.result(context); - } - @Nullable public String group() { return group; diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomBrewingRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomBrewingRecipe.java index 7cb0e8763..1b622acfc 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomBrewingRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomBrewingRecipe.java @@ -47,11 +47,6 @@ public class CustomBrewingRecipe implements FixedResultRecipe { return this.container.test(brewingInput.container()) && this.ingredient.test(brewingInput.ingredient()); } - @Override - public T assemble(RecipeInput input, ItemBuildContext context) { - return this.result(context); - } - @Override public List> ingredientsInUse() { List> ingredients = new ArrayList<>(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomRecipeResult.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomRecipeResult.java index c09aa7c22..ea35480b2 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomRecipeResult.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomRecipeResult.java @@ -1,11 +1,74 @@ package net.momirealms.craftengine.core.item.recipe; import net.momirealms.craftengine.core.item.BuildableItem; +import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; +import net.momirealms.craftengine.core.item.modifier.ItemDataModifier; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.registry.BuiltInRegistries; +import net.momirealms.craftengine.core.registry.Registries; +import net.momirealms.craftengine.core.registry.WritableRegistry; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.ResourceKey; -public record CustomRecipeResult(BuildableItem item, int count) { +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +@SuppressWarnings("unchecked") +public record CustomRecipeResult(BuildableItem item, int count, PostProcessor[] postProcessors) { public T buildItemStack(ItemBuildContext context) { - return item.buildItemStack(context, count); + Item builtItem = this.item.buildItem(context, count); + if (this.postProcessors != null) { + for (PostProcessor postProcessor : this.postProcessors) { + builtItem = postProcessor.process(builtItem, context); + } + } + return builtItem.getItem(); + } + + static { + registerPostProcessorType(Key.of("apply_data"), args -> { + List> modifiers = new ArrayList<>(); + for (Map.Entry entry : args.entrySet()) { + Optional.ofNullable(CraftEngine.instance().itemManager().getDataType(entry.getKey())).ifPresent(it -> { + modifiers.add(it.apply(entry.getValue())); + }); + } + return new ApplyItemDataProcessor<>(modifiers.toArray(new ItemDataModifier[0])); + }); + } + + public static void registerPostProcessorType(Key id, PostProcessor.Type type) { + ((WritableRegistry>) BuiltInRegistries.RECIPE_POST_PROCESSOR_TYPE).register(ResourceKey.create(Registries.RECIPE_POST_PROCESSOR_TYPE.location(), id), type); + } + + @FunctionalInterface + public interface PostProcessor { + + Item process(Item item, ItemBuildContext context); + + interface Type { + + PostProcessor create(Map args); + } + } + + public static class ApplyItemDataProcessor implements PostProcessor { + private final ItemDataModifier[] modifiers; + + public ApplyItemDataProcessor(ItemDataModifier[] modifiers) { + this.modifiers = modifiers; + } + + @Override + public Item process(Item item, ItemBuildContext context) { + for (ItemDataModifier modifier : this.modifiers) { + item.apply(modifier, context); + } + return item; + } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmithingTransformRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmithingTransformRecipe.java index e80872c11..ae26068cd 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmithingTransformRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmithingTransformRecipe.java @@ -154,6 +154,7 @@ public class CustomSmithingTransformRecipe implements FixedResultRecipe { public static class ItemDataProcessors { public static final Key KEEP_COMPONENTS = Key.of("craftengine:keep_components"); public static final Key KEEP_TAGS = Key.of("craftengine:keep_tags"); + public static final Key APPLY_DATA = Key.of("craftengine:apply_data"); static { if (VersionHelper.isOrAbove1_20_5()) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/FixedResultRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/FixedResultRecipe.java index cbc2df693..6a17c507c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/FixedResultRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/FixedResultRecipe.java @@ -1,10 +1,16 @@ package net.momirealms.craftengine.core.item.recipe; import net.momirealms.craftengine.core.item.ItemBuildContext; +import net.momirealms.craftengine.core.item.recipe.input.RecipeInput; public interface FixedResultRecipe extends Recipe { T result(ItemBuildContext context); CustomRecipeResult result(); + + @Override + default T assemble(RecipeInput input, ItemBuildContext context) { + return this.result(context); + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeFactory.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeFactory.java index 6620b3b5c..563b8ca1c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeFactory.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeFactory.java @@ -27,7 +27,8 @@ public interface RecipeFactory { return new CustomRecipeResult( CraftEngine.instance().itemManager().getBuildableItem(Key.of(id)).orElseThrow( () -> new LocalizedResourceConfigException("warning.config.recipe.invalid_result", id)), - count + count, + null ); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/registry/BuiltInRegistries.java b/core/src/main/java/net/momirealms/craftengine/core/registry/BuiltInRegistries.java index 0314031ad..a88ef798b 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/registry/BuiltInRegistries.java +++ b/core/src/main/java/net/momirealms/craftengine/core/registry/BuiltInRegistries.java @@ -6,6 +6,7 @@ import net.momirealms.craftengine.core.block.properties.PropertyFactory; import net.momirealms.craftengine.core.entity.furniture.HitBoxFactory; import net.momirealms.craftengine.core.item.behavior.ItemBehaviorFactory; import net.momirealms.craftengine.core.item.equipment.EquipmentFactory; +import net.momirealms.craftengine.core.item.recipe.CustomRecipeResult; import net.momirealms.craftengine.core.item.recipe.CustomSmithingTransformRecipe; import net.momirealms.craftengine.core.item.recipe.RecipeFactory; import net.momirealms.craftengine.core.item.recipe.network.legacy.LegacyRecipe; @@ -74,6 +75,7 @@ public class BuiltInRegistries { public static final Registry SLOT_DISPLAY_TYPE = createConstantBoundRegistry(Registries.SLOT_DISPLAY_TYPE); public static final Registry RECIPE_DISPLAY_TYPE = createConstantBoundRegistry(Registries.RECIPE_DISPLAY_TYPE); public static final Registry LEGACY_RECIPE_TYPE = createConstantBoundRegistry(Registries.LEGACY_RECIPE_TYPE); + public static final Registry> RECIPE_POST_PROCESSOR_TYPE = createConstantBoundRegistry(Registries.RECIPE_POST_PROCESSOR_TYPE); private static Registry createConstantBoundRegistry(ResourceKey> key) { return new ConstantBoundRegistry<>(key); diff --git a/core/src/main/java/net/momirealms/craftengine/core/registry/Registries.java b/core/src/main/java/net/momirealms/craftengine/core/registry/Registries.java index cbdfba555..382277302 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/registry/Registries.java +++ b/core/src/main/java/net/momirealms/craftengine/core/registry/Registries.java @@ -6,6 +6,7 @@ import net.momirealms.craftengine.core.block.properties.PropertyFactory; import net.momirealms.craftengine.core.entity.furniture.HitBoxFactory; import net.momirealms.craftengine.core.item.behavior.ItemBehaviorFactory; import net.momirealms.craftengine.core.item.equipment.EquipmentFactory; +import net.momirealms.craftengine.core.item.recipe.CustomRecipeResult; import net.momirealms.craftengine.core.item.recipe.CustomSmithingTransformRecipe; import net.momirealms.craftengine.core.item.recipe.RecipeFactory; import net.momirealms.craftengine.core.item.recipe.network.legacy.LegacyRecipe; @@ -42,7 +43,6 @@ import net.momirealms.craftengine.core.util.ResourceKey; public class Registries { public static final Key ROOT_REGISTRY = Key.withDefaultNamespace("root"); public static final ResourceKey> BLOCK = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("block")); - public static final ResourceKey> OPTIMIZED_ITEM_ID = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("optimized_item_id")); public static final ResourceKey> PROPERTY_FACTORY = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("property_factory")); public static final ResourceKey> BLOCK_BEHAVIOR_FACTORY = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("block_behavior_factory")); public static final ResourceKey> ITEM_BEHAVIOR_FACTORY = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("item_behavior_factory")); @@ -77,4 +77,5 @@ public class Registries { public static final ResourceKey> SLOT_DISPLAY_TYPE = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("slot_display_type")); public static final ResourceKey> RECIPE_DISPLAY_TYPE = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("recipe_display_type")); public static final ResourceKey> LEGACY_RECIPE_TYPE = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("legacy_recipe_type")); + public static final ResourceKey>> RECIPE_POST_PROCESSOR_TYPE = ResourceKey.create(ROOT_REGISTRY, Key.withDefaultNamespace("recipe_post_processor_type")); } From 07804a845985de335e40567e720efd8d0e432d0b Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Thu, 17 Jul 2025 20:42:47 +0800 Subject: [PATCH 7/8] =?UTF-8?q?folia=E7=BB=99=E7=89=A9=E5=93=81=E8=B5=B0?= =?UTF-8?q?=E5=AE=9E=E4=BD=93=E8=B0=83=E5=BA=A6=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/command/feature/GiveItemCommand.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/GiveItemCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/GiveItemCommand.java index fd056399e..c79161a19 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/GiveItemCommand.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/GiveItemCommand.java @@ -2,6 +2,7 @@ package net.momirealms.craftengine.bukkit.plugin.command.feature; import net.kyori.adventure.text.Component; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; +import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; import net.momirealms.craftengine.bukkit.util.PlayerUtils; import net.momirealms.craftengine.core.item.CustomItem; @@ -10,6 +11,7 @@ import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager; import net.momirealms.craftengine.core.plugin.command.FlagKeys; import net.momirealms.craftengine.core.plugin.locale.MessageConstants; import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.VersionHelper; import org.bukkit.NamespacedKey; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -74,9 +76,17 @@ public class GiveItemCommand extends BukkitCommandFeature { ItemStack more = builtItem.clone(); more.setAmount(perStackSize); if (toInv) { - PlayerUtils.putItemsToInventory(player.getInventory(), more, more.getAmount()); + if (VersionHelper.isFolia()) { + player.getScheduler().run(plugin().javaPlugin(), (t) -> PlayerUtils.putItemsToInventory(player.getInventory(), more, more.getAmount()), () -> {}); + } else { + PlayerUtils.putItemsToInventory(player.getInventory(), more, more.getAmount()); + } } else { - PlayerUtils.dropItem(player, more, false, true, false); + if (VersionHelper.isFolia()) { + player.getScheduler().run(plugin().javaPlugin(), (t) -> PlayerUtils.dropItem(player, more, false, true, false), () -> {}); + } else { + PlayerUtils.dropItem(player, more, false, true, false); + } } } } From 755657617936f7cab8eae49ae1d037d04b4dda90 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Fri, 18 Jul 2025 04:03:19 +0800 Subject: [PATCH 8/8] 1.21.8 --- .../bukkit/item/factory/BukkitItemFactory.java | 2 +- .../bukkit/plugin/command/feature/GiveItemCommand.java | 1 - .../craftengine/core/util/MinecraftVersion.java | 3 ++- .../craftengine/core/util/MinecraftVersions.java | 1 + .../momirealms/craftengine/core/util/VersionHelper.java | 6 ++++++ gradle.properties | 8 ++++---- 6 files changed, 14 insertions(+), 7 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java index 42447daec..0c5ee3b3c 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java @@ -49,7 +49,7 @@ public abstract class BukkitItemFactory> extend case "1.21.4" -> { return new ComponentItemFactory1_21_4(plugin); } - case "1.21.5", "1.21.6", "1.21.7", "1.22", "1.22.1" -> { + case "1.21.5", "1.21.6", "1.21.7", "1.21.8" -> { return new ComponentItemFactory1_21_5(plugin); } default -> throw new IllegalStateException("Unsupported server version: " + plugin.serverVersion()); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/GiveItemCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/GiveItemCommand.java index c79161a19..f258b70f4 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/GiveItemCommand.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/GiveItemCommand.java @@ -2,7 +2,6 @@ package net.momirealms.craftengine.bukkit.plugin.command.feature; import net.kyori.adventure.text.Component; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; -import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; import net.momirealms.craftengine.bukkit.util.PlayerUtils; import net.momirealms.craftengine.core.item.CustomItem; diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/MinecraftVersion.java b/core/src/main/java/net/momirealms/craftengine/core/util/MinecraftVersion.java index 75c383dd7..2e20c0a66 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/MinecraftVersion.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/MinecraftVersion.java @@ -20,7 +20,8 @@ public final class MinecraftVersion implements Comparable { PACK_FORMATS.put(1_21_04, 46); PACK_FORMATS.put(1_21_05, 55); PACK_FORMATS.put(1_21_06, 63); - PACK_FORMATS.put(1_21_07, 64); // TODO 1.21.7-rc2 + PACK_FORMATS.put(1_21_07, 64); + PACK_FORMATS.put(1_21_08, 64); PACK_FORMATS.put(1_99_99, 1000); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/MinecraftVersions.java b/core/src/main/java/net/momirealms/craftengine/core/util/MinecraftVersions.java index a368a809a..2f28c73ad 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/MinecraftVersions.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/MinecraftVersions.java @@ -18,5 +18,6 @@ public final class MinecraftVersions { public static final MinecraftVersion V1_21_5 = new MinecraftVersion("1.21.5"); public static final MinecraftVersion V1_21_6 = new MinecraftVersion("1.21.6"); public static final MinecraftVersion V1_21_7 = new MinecraftVersion("1.21.7"); + public static final MinecraftVersion V1_21_8 = new MinecraftVersion("1.21.8"); public static final MinecraftVersion FUTURE = new MinecraftVersion("1.99.99"); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/VersionHelper.java b/core/src/main/java/net/momirealms/craftengine/core/util/VersionHelper.java index f88a0f19d..12e001c79 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/VersionHelper.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/VersionHelper.java @@ -30,6 +30,7 @@ public class VersionHelper { private static final boolean v1_21_5; private static final boolean v1_21_6; private static final boolean v1_21_7; + private static final boolean v1_21_8; static { try (InputStream inputStream = Class.forName("net.minecraft.obfuscate.DontObfuscate").getResourceAsStream("/version.json")) { @@ -64,6 +65,7 @@ public class VersionHelper { v1_21_5 = version >= 12105; v1_21_6 = version >= 12106; v1_21_7 = version >= 12107; + v1_21_8 = version >= 12108; majorVersion = major; minorVersion = minor; @@ -215,4 +217,8 @@ public class VersionHelper { public static boolean isOrAbove1_21_7() { return v1_21_7; } + + public static boolean isOrAbove1_21_8() { + return v1_21_8; + } } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index af7ef18be..649a773b0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,17 +2,17 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.60.2 +project_version=0.0.60.3 config_version=42 lang_version=22 project_group=net.momirealms -latest_supported_version=1.21.7 +latest_supported_version=1.21.8 # Supported languages supported_languages=en,zh_cn,zh_tw,es,tr,de,ru_ru # Dependency settings -paper_version=1.21.7 +paper_version=1.21.8 jetbrains_annotations_version=26.0.2 slf4j_version=2.0.17 log4j_version=2.24.3 @@ -50,7 +50,7 @@ byte_buddy_version=1.17.5 ahocorasick_version=0.6.3 snake_yaml_version=2.4 anti_grief_version=0.18 -nms_helper_version=1.0.35 +nms_helper_version=1.0.36 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.31.23