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 a4c4c12e7..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 @@ -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; @@ -28,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; @@ -39,6 +38,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 +56,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 +70,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") @@ -160,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 @@ -452,4 +455,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/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/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/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/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..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 @@ -10,6 +10,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 +75,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); + } } } } 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..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_1_20, 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 109b6bcd3..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 @@ -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(); @@ -2245,9 +2228,70 @@ public class PacketConsumers { } }; + public static final BiConsumer CONTAINER_CLICK_1_21_5 = (user, event) -> { + try { + 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)); + 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 { - if (VersionHelper.isOrAbove1_21_5()) return; // 1.21.5+需要其他办法解决同步问题 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..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 @@ -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 DynamicOps HASHCODE; // 1.21.5+ // 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/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")); } 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 6c5b9b256..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.34 +nms_helper_version=1.0.36 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.31.23