From 9e779e57d22758a383f38d075eea1264bbf2ed4e Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Sun, 2 Nov 2025 17:26:44 +0800 Subject: [PATCH 01/37] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=A4=E4=BA=92?= =?UTF-8?q?=E5=B1=95=E7=A4=BA=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../craftengine/bukkit/util/InteractUtils.java | 14 ++++++++++++++ .../craftengine/core/block/BlockKeys.java | 13 +++++++++++++ .../craftengine/core/pack/AbstractPackManager.java | 4 ---- gradle.properties | 2 +- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/InteractUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/InteractUtils.java index 069deb791..206150f9a 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/InteractUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/InteractUtils.java @@ -34,6 +34,7 @@ import org.bukkit.attribute.AttributeInstance; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Directional; import org.bukkit.block.data.Levelled; import org.bukkit.block.data.Lightable; import org.bukkit.block.data.type.*; @@ -714,6 +715,19 @@ public final class InteractUtils { registerInteraction(BlockKeys.BAMBOO_WALL_HANGING_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.CRIMSON_WALL_HANGING_SIGN, (player, item, blockState, result) -> true); registerInteraction(BlockKeys.WARPED_WALL_HANGING_SIGN, (player, item, blockState, result) -> true); + // 展示柜 + registerInteraction(BlockKeys.OAK_SHELF, (player, item, blockState, result) -> blockState instanceof Directional directional && DirectionUtils.toBlockFace(result.getDirection()).equals(directional.getFacing())); + registerInteraction(BlockKeys.SPRUCE_SHELF, (player, item, blockState, result) -> blockState instanceof Directional directional && DirectionUtils.toBlockFace(result.getDirection()).equals(directional.getFacing())); + registerInteraction(BlockKeys.BIRCH_SHELF, (player, item, blockState, result) -> blockState instanceof Directional directional && DirectionUtils.toBlockFace(result.getDirection()).equals(directional.getFacing())); + registerInteraction(BlockKeys.JUNGLE_SHELF, (player, item, blockState, result) -> blockState instanceof Directional directional && DirectionUtils.toBlockFace(result.getDirection()).equals(directional.getFacing())); + registerInteraction(BlockKeys.ACACIA_SHELF, (player, item, blockState, result) -> blockState instanceof Directional directional && DirectionUtils.toBlockFace(result.getDirection()).equals(directional.getFacing())); + registerInteraction(BlockKeys.DARK_OAK_SHELF, (player, item, blockState, result) -> blockState instanceof Directional directional && DirectionUtils.toBlockFace(result.getDirection()).equals(directional.getFacing())); + registerInteraction(BlockKeys.MANGROVE_SHELF, (player, item, blockState, result) -> blockState instanceof Directional directional && DirectionUtils.toBlockFace(result.getDirection()).equals(directional.getFacing())); + registerInteraction(BlockKeys.CHERRY_SHELF, (player, item, blockState, result) -> blockState instanceof Directional directional && DirectionUtils.toBlockFace(result.getDirection()).equals(directional.getFacing())); + registerInteraction(BlockKeys.PALE_OAK_SHELF, (player, item, blockState, result) -> blockState instanceof Directional directional && DirectionUtils.toBlockFace(result.getDirection()).equals(directional.getFacing())); + registerInteraction(BlockKeys.BAMBOO_SHELF, (player, item, blockState, result) -> blockState instanceof Directional directional && DirectionUtils.toBlockFace(result.getDirection()).equals(directional.getFacing())); + registerInteraction(BlockKeys.CRIMSON_SHELF, (player, item, blockState, result) -> blockState instanceof Directional directional && DirectionUtils.toBlockFace(result.getDirection()).equals(directional.getFacing())); + registerInteraction(BlockKeys.WARPED_SHELF, (player, item, blockState, result) -> blockState instanceof Directional directional && DirectionUtils.toBlockFace(result.getDirection()).equals(directional.getFacing())); } static { diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/BlockKeys.java b/core/src/main/java/net/momirealms/craftengine/core/block/BlockKeys.java index 84a6e13f0..27bfb7cae 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/BlockKeys.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/BlockKeys.java @@ -330,6 +330,19 @@ public final class BlockKeys { public static final Key CHERRY_SAPLING = Key.of("minecraft:cherry_sapling"); public static final Key PALE_OAK_SAPLING = Key.of("minecraft:pale_oak_sapling"); + public static final Key OAK_SHELF = Key.of("minecraft:oak_shelf"); + public static final Key SPRUCE_SHELF = Key.of("minecraft:spruce_shelf"); + public static final Key BIRCH_SHELF = Key.of("minecraft:birch_shelf"); + public static final Key JUNGLE_SHELF = Key.of("minecraft:jungle_shelf"); + public static final Key ACACIA_SHELF = Key.of("minecraft:acacia_shelf"); + public static final Key DARK_OAK_SHELF = Key.of("minecraft:dark_oak_shelf"); + public static final Key MANGROVE_SHELF = Key.of("minecraft:mangrove_shelf"); + public static final Key CHERRY_SHELF = Key.of("minecraft:cherry_shelf"); + public static final Key PALE_OAK_SHELF = Key.of("minecraft:pale_oak_shelf"); + public static final Key BAMBOO_SHELF = Key.of("minecraft:bamboo_shelf"); + public static final Key CRIMSON_SHELF = Key.of("minecraft:crimson_shelf"); + public static final Key WARPED_SHELF = Key.of("minecraft:warped_shelf"); + public static final Key[] BUTTONS = new Key[]{ OAK_BUTTON, SPRUCE_BUTTON, BIRCH_BUTTON, JUNGLE_BUTTON, ACACIA_BUTTON, DARK_OAK_BUTTON, MANGROVE_BUTTON, CHERRY_BUTTON, PALE_OAK_BUTTON, BAMBOO_BUTTON, CRIMSON_BUTTON, WARPED_BUTTON, STONE_BUTTON, POLISHED_BLACKSTONE_BUTTON diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java index e43115a29..8f165a669 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java @@ -734,10 +734,6 @@ public abstract class AbstractPackManager implements PackManager { this.plugin.logger().info("Optimized resource pack in " + (time4 - time3) + "ms"); Path finalPath = resourcePackPath(); Files.createDirectories(finalPath.getParent()); - if (!VersionHelper.PREMIUM && Config.enableObfuscation()) { - Config.instance().setObf(false); - this.plugin.logger().warn("Resource pack obfuscation requires Premium Edition."); - } try { this.zipGenerator.accept(generatedPackPath, finalPath); } catch (Exception e) { diff --git a/gradle.properties b/gradle.properties index 25deb2efa..be05e23a9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.65 +project_version=0.0.65.1 config_version=52 lang_version=36 project_group=net.momirealms From ec9d048beb9f77f41925f0cce9d51d2a3c5b168e Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Sun, 2 Nov 2025 18:06:49 +0800 Subject: [PATCH 02/37] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 26b55747f..2f45c4583 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ repositories { ``` ```kotlin dependencies { - compileOnly("net.momirealms:craft-engine-core:0.0.64") - compileOnly("net.momirealms:craft-engine-bukkit:0.0.64") + compileOnly("net.momirealms:craft-engine-core:0.0.65") + compileOnly("net.momirealms:craft-engine-bukkit:0.0.65") } ``` \ No newline at end of file From fbda3a954b942065a31495301a7448bb80407a3a Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Mon, 3 Nov 2025 08:27:45 +0800 Subject: [PATCH 03/37] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 font 冲突处理器 - 修复方块实体中的客户端侧物品显示 - 更新简体中文语言 --- .../plugin/network/BukkitNetworkManager.java | 24 ++++++-- .../src/main/resources/translations/zh_cn.yml | 39 +++++++++---- .../resolution/ResolutionMergeAltas.java | 2 +- .../resolution/ResolutionMergeFont.java | 57 +++++++++++++++++++ .../pack/conflict/resolution/Resolutions.java | 2 + gradle.properties | 4 +- 6 files changed, 107 insertions(+), 21 deletions(-) create mode 100644 core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/ResolutionMergeFont.java 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 6bb11d66e..f7a0ec525 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 @@ -4132,16 +4132,22 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes CompoundTag tag = (CompoundTag) buf.readNbt(named); // todo 刷怪笼里的物品? - // 展示架 - if (VersionHelper.isOrAbove1_21_9() && tag != null && tag.containsKey("Items")) { + // 通用方块实体存储的物品 + if (tag != null && tag.containsKey("Items")) { BukkitItemManager itemManager = BukkitItemManager.instance(); ListTag itemsTag = tag.getList("Items"); List> items = new ArrayList<>(); for (Tag itemTag : itemsTag) { if (itemTag instanceof CompoundTag itemCompoundTag) { byte slot = itemCompoundTag.getByte("Slot"); - Object nmsStack = CoreReflections.instance$ItemStack$CODEC.parse(MRegistryOps.SPARROW_NBT, itemCompoundTag) - .resultOrPartial((error) -> CraftEngine.instance().logger().severe("Tried to parse invalid item: '" + error + "'")).orElse(null); + Object nmsStack; + if (VersionHelper.isOrAbove1_20_5()) { + nmsStack = CoreReflections.instance$ItemStack$CODEC.parse(MRegistryOps.SPARROW_NBT, itemCompoundTag) + .resultOrPartial((error) -> CraftEngine.instance().logger().severe("Tried to parse invalid item: '" + error + "'")).orElse(null); + } else { + Object nmsTag = MRegistryOps.SPARROW_NBT.convertTo(MRegistryOps.NBT, itemTag); + nmsStack = FastNMS.INSTANCE.method$ItemStack$of(nmsTag); + } ItemStack bukkitStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(nmsStack); Optional optional = itemManager.s2c(bukkitStack, (BukkitServerPlayer) user); if (optional.isPresent()) { @@ -4155,8 +4161,14 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes if (changed) { ListTag newItemsTag = new ListTag(); for (Pair pair : items) { - CompoundTag newItemCompoundTag = (CompoundTag) CoreReflections.instance$ItemStack$CODEC.encodeStart(MRegistryOps.SPARROW_NBT, FastNMS.INSTANCE.field$CraftItemStack$handle(pair.right())) - .resultOrPartial((error) -> CraftEngine.instance().logger().severe("Tried to encode invalid item: '" + error + "'")).orElse(null); + CompoundTag newItemCompoundTag; + if (VersionHelper.isOrAbove1_20_5()) { + newItemCompoundTag = (CompoundTag) CoreReflections.instance$ItemStack$CODEC.encodeStart(MRegistryOps.SPARROW_NBT, FastNMS.INSTANCE.field$CraftItemStack$handle(pair.right())) + .resultOrPartial((error) -> CraftEngine.instance().logger().severe("Tried to encode invalid item: '" + error + "'")).orElse(null); + } else { + Object nmsTag = FastNMS.INSTANCE.method$itemStack$save(FastNMS.INSTANCE.field$CraftItemStack$handle(pair.right()), FastNMS.INSTANCE.constructor$CompoundTag()); + newItemCompoundTag = (CompoundTag) MRegistryOps.NBT.convertTo(MRegistryOps.SPARROW_NBT, nmsTag); + } if (newItemCompoundTag != null) { newItemCompoundTag.putByte("Slot", pair.left()); newItemsTag.add(newItemCompoundTag); diff --git a/common-files/src/main/resources/translations/zh_cn.yml b/common-files/src/main/resources/translations/zh_cn.yml index 95a857b0e..b2a6c3685 100644 --- a/common-files/src/main/resources/translations/zh_cn.yml +++ b/common-files/src/main/resources/translations/zh_cn.yml @@ -65,6 +65,9 @@ command.upload.failure.not_supported: "当前托管模式 '' 不支 command.upload.on_progress: "已开始上传进程. 检查控制台以获取详细信息" command.send_resource_pack.success.single: "发送资源包给 " command.send_resource_pack.success.multiple: "发送资源包给 个玩家" +command.locale.set.failure: "区域设置格式无效: " +command.locale.set.success: "已为 更新选定区域设置为 " +command.locale.unset.success: "已清除 的选定区域设置" warning.network.resource_pack.unverified_uuid: "玩家 使用未经服务器验证的 UUID () 尝试请求获取资源包" warning.config.pack.duplicated_files: "发现重复文件 请通过 config.yml 的 'resource-pack.duplicated-files-handler' 部分解决" warning.config.yaml.duplicated_key: "在文件 发现问题 - 在第行发现重复的键 '', 这可能会导致一些意料之外的问题" @@ -160,10 +163,10 @@ warning.config.recipe.result.post_processor.missing_type: "在文件 在文件 发现问题 - 配方 '' 使用了无效结果后处理器类型 ''" warning.config.translation.unknown_locale: "在文件 发现问题 - 未知的语言环境 ''" warning.config.template.duplicate: "在文件 发现问题 - 重复的模板 '' 请检查其他文件中是否存在相同配置" -warning.config.template.invalid: "在文件 发现问题 - 配置 '' 使用了无效的模板 ''" +warning.config.template.invalid: "在文件 发现问题 - 配置项 '' 使用了无效的模板 ''" warning.config.template.argument.self_increase_int.invalid_range: "在文件 发现问题 - 模板 '' 在 'self_increase_int' 参数中使用了一个起始值 '' 大于终止值 ''" warning.config.template.argument.list.invalid_type: "在文件 发现问题 - 模板 '' 的 'list' 参数需要列表类型 但输入参数类型为 ''" -warning.config.template.argument.missing_value: "在文件 发现问题 - 配置 '' 缺少了 '' 必要的模板参数值. 请使用 arguments 选项进行配置或为此参数设定默认值" +warning.config.template.argument.missing_value: "在文件 发现问题 - 配置项 '' 缺少了 '' 必要的模板参数值. 请使用 arguments 选项进行配置或为此参数设定默认值" warning.config.vanilla_loot.missing_type: "在文件 发现问题 - 原版战利品 '' 缺少必需的 'type' 参数" warning.config.vanilla_loot.invalid_type: "在文件 发现问题 - 原版战利品 '' 使用了无效类型 '' 允许的类型: []" warning.config.vanilla_loot.block.invalid_target: "在文件 发现问题 - 原版战利品 '' 中存在无效的方块目标 ''" @@ -184,6 +187,10 @@ warning.config.item.settings.invulnerable.invalid_damage_source: "在文 warning.config.item.settings.equipment.missing_asset_id: "在文件 发现问题 - 物品 '' 缺少 'equipment' 设置所需的 'asset-id' 参数" warning.config.item.settings.equipment.invalid_asset_id: "在文件 发现问题 - 物品 '' 为 'equipment' 设置配置了无效的 'asset-id'. 这可能是因为你没有创建装备配置或是错误地拼写了 asset-id" warning.config.item.settings.projectile.missing_item: "在文件 发现问题 - 物品 '' 缺少 'projectile' 设置所需的 'item' 参数" +warning.config.item.settings.craft_remainder.missing_type: "在文件 发现问题 - 物品 '' 缺少 'craft-remainder' 所需的 'type' 参数" +warning.config.item.settings.craft_remainder.invalid_type: "在文件 发现问题 - 物品 '' 使用了无效的合成剩余物品类型 ''" +warning.config.item.settings.craft_remainder.fixed.missing_item: "在文件 发现问题 - 物品 '' 的固定 'craft-remainder' 缺少所需的 'item' 参数" +warning.config.item.settings.craft_remainder.recipe_based.missing_terms: "在文件 发现问题 - 物品 '' 缺少基于配方的 'craft-remainder' 所需的 'terms' 参数" warning.config.item.data.attribute_modifiers.missing_type: "在文件 发现问题 - 物品 '' 缺少 'attribute-modifiers' 数据所需的 'type' 参数" warning.config.item.data.attribute_modifiers.missing_amount: "在文件 发现问题 - 物品 '' 缺少 'attribute-modifiers' 数据所需的 'amount' 参数" warning.config.item.data.attribute_modifiers.missing_operation: "在文件 发现问题 - 物品 '' 缺少 'attribute-modifiers' 数据所需的 'operation' 参数" @@ -263,8 +270,8 @@ warning.config.item.model.special.copper_golem_statue.missing_texture: " warning.config.item.updater.missing_type: "在文件 发现问题 - 物品 '' 缺少物品更新器必需的参数 'type'" warning.config.item.updater.invalid_type: "在文件 发现问题 - 物品 '' 在物品更新器中使用了无效的 'type' 参数值 ''" warning.config.item.updater.transmute.missing_material: "在文件 发现问题 - 物品 '' 缺少物品转换更新所需的 'material' 参数" -warning.config.block_state_mapping.invalid_state: "在文件 发现问题 - 配置 '' 使用了无效的方块状态 ''" -warning.config.block_state_mapping.conflict: "在文件 发现问题 - 配置 '' 无法将方块状态 映射到方块状态 , 因为该状态已被映射到 " +warning.config.block_state_mapping.invalid_state: "在文件 发现问题 - 配置项 '' 使用了无效的方块状态 ''" +warning.config.block_state_mapping.conflict: "在文件 发现问题 - 配置项 '' 无法将方块状态 映射到方块状态 , 因为该状态已被映射到 " warning.config.block.duplicate: "在文件 发现问题 - 重复的方块 '' 请检查其他文件中是否存在相同配置" warning.config.block.missing_state: "在文件 发现问题 - 方块 '' 缺少必需的 'state' 参数" warning.config.block.state.property.missing_type: "在文件 发现问题 - 方块 '' 的属性 '' 缺少必需的 'type' 参数" @@ -454,14 +461,21 @@ warning.config.function.remove_cooldown.missing_id: "在文件 warning.config.function.mythic_mobs_skill.missing_skill: "在文件 发现问题 - 配置项 '' 缺少 'mythic_mobs_skill' 函数必需的 'skill' 参数" warning.config.function.spawn_furniture.missing_furniture_id: "在文件 发现问题 - 配置项 '' 缺少 'spawn_furniture' 函数必需的 'furniture-id' 参数" warning.config.function.replace_furniture.missing_furniture_id: "在文件 发现问题 - 配置项 '' 缺少 'replace_furniture' 函数必需的 'furniture-id' 参数" -warning.config.function.teleport.missing_x: "在文件 发现问题 - 配置 '' 缺少 'teleport' 函数所需的 'x' 参数" -warning.config.function.teleport.missing_y: "在文件 发现问题 - 配置 '' 缺少 'teleport' 函数所需的 'y' 参数" -warning.config.function.teleport.missing_z: "在文件 发现问题 - 配置 '' 缺少 'teleport' 函数所需的 'z' 参数" -warning.config.function.set_variable.missing_name: "在文件 发现问题 - 配置 '' 缺少 'set_variable' 函数所需的 'name' 参数" -warning.config.function.set_variable.missing_value: "在文件 发现问题 - 配置 '' 缺少 'set_variable' 函数所需的 'number' 或 'text' 参数" -warning.config.function.toast.missing_toast: "在文件 发现问题 - 配置 '' 缺少 'toast' 函数所需的 'toast' 参数" -warning.config.function.toast.missing_icon: "在文件 发现问题 - 配置 '' 缺少 'toast' 函数所需的 'icon' 参数" -warning.config.function.toast.invalid_advancement_type: "在文件 发现问题 - 配置 '' 为 'toast' 函数使用了无效的进度类型 ''. 允许的类型: []" +warning.config.function.teleport.missing_x: "在文件 发现问题 - 配置项 '' 缺少 'teleport' 函数所需的 'x' 参数" +warning.config.function.teleport.missing_y: "在文件 发现问题 - 配置项 '' 缺少 'teleport' 函数所需的 'y' 参数" +warning.config.function.teleport.missing_z: "在文件 发现问题 - 配置项 '' 缺少 'teleport' 函数所需的 'z' 参数" +warning.config.function.set_variable.missing_name: "在文件 发现问题 - 配置项 '' 缺少 'set_variable' 函数所需的 'name' 参数" +warning.config.function.set_variable.missing_value: "在文件 发现问题 - 配置项 '' 缺少 'set_variable' 函数所需的 'number' 或 'text' 参数" +warning.config.function.toast.missing_toast: "在文件 发现问题 - 配置项 '' 缺少 'toast' 函数所需的 'toast' 参数" +warning.config.function.toast.missing_icon: "在文件 发现问题 - 配置项 '' 缺少 'toast' 函数所需的 'icon' 参数" +warning.config.function.toast.invalid_advancement_type: "在文件 发现问题 - 配置项 '' 为 'toast' 函数使用了无效的进度类型 ''. 允许的类型: []" +warning.config.function.merchant_trade.missing_offers: "在文件 发现问题 - 配置项 '' 缺少 'merchant_trade' 函数所需的 'offers' 参数" +warning.config.function.merchant_trade.offer.missing_cost_1: "在文件 发现问题 - 配置项 '' 缺少'merchant_trade' 函数所需的 'cost-1' 参数" +warning.config.function.merchant_trade.offer.missing_result: "在文件 发现问题 - 配置项 '' 缺少'merchant_trade' 函数所需的 'result' 参数" +warning.config.function.when.missing_source: "在文件 发现问题 - 配置项 '' 缺少 'when' 函数所需的 'source' 参数" +warning.config.function.if_else.missing_rules: "在文件 发现问题 - 配置项 '' 缺少 'if_else' 函数所需的 'rules' 参数" +warning.config.function.update_block_property.missing_properties: "在文件 发现问题 - 配置项 '' 缺少 'update_block_property' 函数所需的 'properties' 参数" +warning.config.function.transform_block.missing_block: "在文件 发现问题 - 配置项 '' 缺少 'transform_block' 函数所需的 'block' 参数" warning.config.selector.missing_type: "在文件 发现问题 - 配置项 '' 缺少选择器必需的 'type' 参数" warning.config.selector.invalid_type: "在文件 发现问题 - 配置项 '' 使用了无效的选择器类型 ''" warning.config.selector.invalid_target: "在文件 发现问题 - 配置项 '' 使用了无效的选择器目标 ''" @@ -474,6 +488,7 @@ warning.config.resource_pack.generation.missing_item_model: "物品'方块状态''缺少模型文件: ''" warning.config.resource_pack.generation.missing_parent_model: "模型''找不到父级模型文件: ''" warning.config.resource_pack.generation.missing_equipment_texture: "装备 '' 缺少纹理 ''" +warning.config.resource_pack.generation.missing_sound: "声音事件 '' 缺少 ogg 文件 ''" warning.config.resource_pack.generation.texture_not_in_atlas: "纹理''不在图集内. 你需要将纹理路径或文件夹前缀添加到图集内, 或者启用 config.yml 中的 'fix-atlas' 选项" warning.config.resource_pack.invalid_overlay_format: "在 config.yml 的 'resource-pack.overlay-format' 处发现问题 - 无效的overlay格式 ''. Overlay格式必须包含占位符 '{version}'" warning.config.equipment.duplicate: "在文件 发现问题 - 重复的装备配置 ''. 请检查其他文件中是否存在相同配置" diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/ResolutionMergeAltas.java b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/ResolutionMergeAltas.java index 65e0daf81..4d1547ab5 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/ResolutionMergeAltas.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/ResolutionMergeAltas.java @@ -38,7 +38,7 @@ public class ResolutionMergeAltas implements Resolution { j3.add("sources", ja3); GsonHelper.writeJsonFile(j3, existing.path()); } catch (Exception e) { - CraftEngine.instance().logger().severe("Failed to merge json when resolving file conflicts", e); + CraftEngine.instance().logger().severe("Failed to merge altas when resolving file conflicts", e); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/ResolutionMergeFont.java b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/ResolutionMergeFont.java new file mode 100644 index 000000000..c8beb26dc --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/ResolutionMergeFont.java @@ -0,0 +1,57 @@ +package net.momirealms.craftengine.core.pack.conflict.resolution; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import net.momirealms.craftengine.core.pack.conflict.PathContext; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.util.GsonHelper; +import net.momirealms.craftengine.core.util.Key; + +import java.util.HashSet; +import java.util.Map; + +public class ResolutionMergeFont implements Resolution { + public static final Factory FACTORY = new Factory(); + public static final ResolutionMergeFont INSTANCE = new ResolutionMergeFont(); + + @Override + public void run(PathContext existing, PathContext conflict) { + try { + JsonObject j1 = GsonHelper.readJsonFile(existing.path()).getAsJsonObject(); + JsonObject j2 = GsonHelper.readJsonFile(conflict.path()).getAsJsonObject(); + JsonObject j3 = new JsonObject(); + JsonArray ja1 = j1.getAsJsonArray("providers"); + JsonArray ja2 = j2.getAsJsonArray("providers"); + JsonArray ja3 = new JsonArray(); + HashSet elements = new HashSet<>(); + for (JsonElement je : ja1) { + if (elements.add(je.toString())) { + ja3.add(je); + } + } + for (JsonElement je : ja2) { + if (elements.add(je.toString())) { + ja3.add(je); + } + } + j3.add("providers", ja3); + GsonHelper.writeJsonFile(j3, existing.path()); + } catch (Exception e) { + CraftEngine.instance().logger().severe("Failed to merge font when resolving file conflicts", e); + } + } + + @Override + public Key type() { + return Resolutions.MERGE_FONT; + } + + public static class Factory implements ResolutionFactory { + + @Override + public Resolution create(Map arguments) { + return INSTANCE; + } + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/Resolutions.java b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/Resolutions.java index f7651d881..ca5e761b0 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/Resolutions.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/Resolutions.java @@ -14,6 +14,7 @@ public class Resolutions { public static final Key RETAIN_MATCHING = Key.of("craftengine:retain_matching"); public static final Key MERGE_JSON = Key.of("craftengine:merge_json"); public static final Key MERGE_ATLAS = Key.of("craftengine:merge_atlas"); + public static final Key MERGE_FONT = Key.of("craftengine:merge_font"); public static final Key CONDITIONAL = Key.of("craftengine:conditional"); public static final Key MERGE_PACK_MCMETA = Key.of("craftengine:merge_pack_mcmeta"); public static final Key MERGE_LEGACY_MODEL = Key.of("craftengine:merge_legacy_model"); @@ -25,6 +26,7 @@ public class Resolutions { register(MERGE_PACK_MCMETA, ResolutionMergePackMcMeta.FACTORY); register(MERGE_ATLAS, ResolutionMergeAltas.FACTORY); register(MERGE_LEGACY_MODEL, ResolutionMergeLegacyModel.FACTORY); + register(MERGE_FONT, ResolutionMergeFont.FACTORY); } public static void register(Key key, ResolutionFactory factory) { diff --git a/gradle.properties b/gradle.properties index be05e23a9..a72bd9b48 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,9 +2,9 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.65.1 +project_version=0.0.65.2 config_version=52 -lang_version=36 +lang_version=37 project_group=net.momirealms latest_supported_version=1.21.10 From 4aa1f5f7cc1378c7ce1532910039cb999ffc835b Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Mon, 3 Nov 2025 08:43:10 +0800 Subject: [PATCH 04/37] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common-files/src/main/resources/config.yml | 9 +++++++++ gradle.properties | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/common-files/src/main/resources/config.yml b/common-files/src/main/resources/config.yml index 53b288014..c818e6167 100644 --- a/common-files/src/main/resources/config.yml +++ b/common-files/src/main/resources/config.yml @@ -81,6 +81,15 @@ resource-pack: suffix: "minecraft/atlases" resolution: type: merge_atlas + - term: + type: any_of + terms: + - type: exact + path: "assets/minecraft/font/default.json" + - type: exact + path: "assets/minecraft/font/uniform.json" + resolution: + type: merge_font # Validate if there is any error in the resource pack, such as missing textures or models # If your resource pack is compliant with the standard, you can disable validation to improve the resource pack generation speed. validation: diff --git a/gradle.properties b/gradle.properties index a72bd9b48..b8c2f4cdf 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] project_version=0.0.65.2 -config_version=52 +config_version=53 lang_version=37 project_group=net.momirealms latest_supported_version=1.21.10 From 5d3afa4a1eef0e10283ac6211872ad3148e79d02 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Tue, 4 Nov 2025 19:50:21 +0800 Subject: [PATCH 05/37] =?UTF-8?q?=E4=BC=98=E5=8C=961.21.9=E6=96=B0?= =?UTF-8?q?=E6=96=B9=E5=9D=97=E7=9A=84=E4=BA=A4=E4=BA=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../craftengine/bukkit/util/InteractUtils.java | 18 ++++++++++++++++++ .../craftengine/core/block/BlockKeys.java | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/InteractUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/InteractUtils.java index 206150f9a..dc44ac1a9 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/InteractUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/InteractUtils.java @@ -728,6 +728,24 @@ public final class InteractUtils { registerInteraction(BlockKeys.BAMBOO_SHELF, (player, item, blockState, result) -> blockState instanceof Directional directional && DirectionUtils.toBlockFace(result.getDirection()).equals(directional.getFacing())); registerInteraction(BlockKeys.CRIMSON_SHELF, (player, item, blockState, result) -> blockState instanceof Directional directional && DirectionUtils.toBlockFace(result.getDirection()).equals(directional.getFacing())); registerInteraction(BlockKeys.WARPED_SHELF, (player, item, blockState, result) -> blockState instanceof Directional directional && DirectionUtils.toBlockFace(result.getDirection()).equals(directional.getFacing())); + // 铜傀儡雕像 + registerInteraction(BlockKeys.COPPER_GOLEM_STATUE, ((player, item, blockData, result) -> true)); + registerInteraction(BlockKeys.EXPOSED_COPPER_GOLEM_STATUE, ((player, item, blockData, result) -> true)); + registerInteraction(BlockKeys.WEATHERED_COPPER_GOLEM_STATUE, ((player, item, blockData, result) -> true)); + registerInteraction(BlockKeys.OXIDIZED_COPPER_GOLEM_STATUE, ((player, item, blockData, result) -> true)); + registerInteraction(BlockKeys.WAXED_COPPER_GOLEM_STATUE, ((player, item, blockData, result) -> true)); + registerInteraction(BlockKeys.WAXED_EXPOSED_COPPER_GOLEM_STATUE, ((player, item, blockData, result) -> true)); + registerInteraction(BlockKeys.WAXED_WEATHERED_COPPER_GOLEM_STATUE, ((player, item, blockData, result) -> true)); + registerInteraction(BlockKeys.WAXED_OXIDIZED_COPPER_GOLEM_STATUE, ((player, item, blockData, result) -> true)); + // 铜箱子 + registerInteraction(BlockKeys.COPPER_CHEST, ((player, item, blockData, result) -> true)); + registerInteraction(BlockKeys.EXPOSED_COPPER_CHEST, ((player, item, blockData, result) -> true)); + registerInteraction(BlockKeys.WEATHERED_COPPER_CHEST, ((player, item, blockData, result) -> true)); + registerInteraction(BlockKeys.OXIDIZED_COPPER_CHEST, ((player, item, blockData, result) -> true)); + registerInteraction(BlockKeys.WAXED_COPPER_CHEST, ((player, item, blockData, result) -> true)); + registerInteraction(BlockKeys.WAXED_EXPOSED_COPPER_CHEST, ((player, item, blockData, result) -> true)); + registerInteraction(BlockKeys.WAXED_WEATHERED_COPPER_CHEST, ((player, item, blockData, result) -> true)); + registerInteraction(BlockKeys.WAXED_OXIDIZED_COPPER_CHEST, ((player, item, blockData, result) -> true)); } static { diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/BlockKeys.java b/core/src/main/java/net/momirealms/craftengine/core/block/BlockKeys.java index 27bfb7cae..f6c63e383 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/BlockKeys.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/BlockKeys.java @@ -343,6 +343,24 @@ public final class BlockKeys { public static final Key CRIMSON_SHELF = Key.of("minecraft:crimson_shelf"); public static final Key WARPED_SHELF = Key.of("minecraft:warped_shelf"); + public static final Key COPPER_GOLEM_STATUE = Key.of("minecraft:copper_golem_statue"); + public static final Key EXPOSED_COPPER_GOLEM_STATUE = Key.of("minecraft:exposed_copper_golem_statue"); + public static final Key WEATHERED_COPPER_GOLEM_STATUE = Key.of("minecraft:weathered_copper_golem_statue"); + public static final Key OXIDIZED_COPPER_GOLEM_STATUE = Key.of("minecraft:oxidized_copper_golem_statue"); + public static final Key WAXED_COPPER_GOLEM_STATUE = Key.of("minecraft:waxed_copper_golem_statue"); + public static final Key WAXED_EXPOSED_COPPER_GOLEM_STATUE = Key.of("minecraft:waxed_exposed_copper_golem_statue"); + public static final Key WAXED_WEATHERED_COPPER_GOLEM_STATUE = Key.of("minecraft:waxed_weathered_copper_golem_statue"); + public static final Key WAXED_OXIDIZED_COPPER_GOLEM_STATUE = Key.of("minecraft:waxed_oxidized_copper_golem_statue"); + + public static final Key COPPER_CHEST = Key.of("minecraft:copper_chest"); + public static final Key EXPOSED_COPPER_CHEST = Key.of("minecraft:exposed_copper_chest"); + public static final Key WEATHERED_COPPER_CHEST = Key.of("minecraft:weathered_copper_chest"); + public static final Key OXIDIZED_COPPER_CHEST = Key.of("minecraft:oxidized_copper_chest"); + public static final Key WAXED_COPPER_CHEST = Key.of("minecraft:waxed_copper_chest"); + public static final Key WAXED_EXPOSED_COPPER_CHEST = Key.of("minecraft:waxed_exposed_copper_chest"); + public static final Key WAXED_WEATHERED_COPPER_CHEST = Key.of("minecraft:waxed_weathered_copper_chest"); + public static final Key WAXED_OXIDIZED_COPPER_CHEST = Key.of("minecraft:waxed_oxidized_copper_chest"); + public static final Key[] BUTTONS = new Key[]{ OAK_BUTTON, SPRUCE_BUTTON, BIRCH_BUTTON, JUNGLE_BUTTON, ACACIA_BUTTON, DARK_OAK_BUTTON, MANGROVE_BUTTON, CHERRY_BUTTON, PALE_OAK_BUTTON, BAMBOO_BUTTON, CRIMSON_BUTTON, WARPED_BUTTON, STONE_BUTTON, POLISHED_BLACKSTONE_BUTTON From 738931873182a2c04e0491eca47110688c108010 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Tue, 4 Nov 2025 19:55:52 +0800 Subject: [PATCH 06/37] =?UTF-8?q?=E4=B8=BAmatch=5Fblock=E6=B7=BB=E5=8A=A0x?= =?UTF-8?q?,y,z=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../condition/MatchBlockCondition.java | 26 ++++++++++++++++--- gradle.properties | 2 +- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/condition/MatchBlockCondition.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/condition/MatchBlockCondition.java index 769e849fa..a26f015e2 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/condition/MatchBlockCondition.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/condition/MatchBlockCondition.java @@ -2,22 +2,32 @@ package net.momirealms.craftengine.core.plugin.context.condition; import net.momirealms.craftengine.core.plugin.context.Condition; import net.momirealms.craftengine.core.plugin.context.Context; +import net.momirealms.craftengine.core.plugin.context.number.NumberProvider; +import net.momirealms.craftengine.core.plugin.context.number.NumberProviders; import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; import net.momirealms.craftengine.core.util.ResourceConfigUtils; import net.momirealms.craftengine.core.world.ExistingBlock; +import net.momirealms.craftengine.core.world.World; +import net.momirealms.craftengine.core.world.WorldPosition; import java.util.*; public class MatchBlockCondition implements Condition { private final Set ids; private final boolean regexMatch; + private final NumberProvider x; + private final NumberProvider y; + private final NumberProvider z; - public MatchBlockCondition(Collection ids, boolean regexMatch) { + public MatchBlockCondition(Collection ids, boolean regexMatch, NumberProvider x, NumberProvider y, NumberProvider z) { this.ids = new HashSet<>(ids); this.regexMatch = regexMatch; + this.x = x; + this.y = y; + this.z = z; } @Override @@ -27,8 +37,13 @@ public class MatchBlockCondition implements Condition @Override public boolean test(CTX ctx) { - Optional block = ctx.getOptionalParameter(DirectContextParameters.BLOCK); - return block.filter(blockInWorld -> MiscUtils.matchRegex(blockInWorld.id().asString(), this.ids, this.regexMatch)).isPresent(); + Optional optionalWorldPosition = ctx.getOptionalParameter(DirectContextParameters.POSITION); + if (optionalWorldPosition.isPresent()) { + World world = optionalWorldPosition.get().world(); + ExistingBlock blockAt = world.getBlockAt(MiscUtils.fastFloor(this.x.getDouble(ctx)), MiscUtils.fastFloor(this.y.getDouble(ctx)), MiscUtils.fastFloor(this.z.getDouble(ctx))); + return MiscUtils.matchRegex(blockAt.id().asString(), this.ids, this.regexMatch); + } + return false; } public static class FactoryImpl implements ConditionFactory { @@ -40,7 +55,10 @@ public class MatchBlockCondition implements Condition throw new LocalizedResourceConfigException("warning.config.condition.match_block.missing_id"); } boolean regex = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("regex", false), "regex"); - return new MatchBlockCondition<>(ids, regex); + return new MatchBlockCondition<>(ids, regex, + NumberProviders.fromObject(arguments.getOrDefault("x", "")), + NumberProviders.fromObject(arguments.getOrDefault("y", "")), + NumberProviders.fromObject(arguments.getOrDefault("z", ""))); } } } diff --git a/gradle.properties b/gradle.properties index b8c2f4cdf..95f82a8aa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.65.2 +project_version=0.0.65.3 config_version=53 lang_version=37 project_group=net.momirealms From bb305343d33b946c703437dfc7bf515dc377023c Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Tue, 4 Nov 2025 22:13:43 +0800 Subject: [PATCH 07/37] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=96=B9=E5=9D=97?= =?UTF-8?q?=E5=AE=9E=E4=BD=93=E5=88=87=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BetterModelBlockEntityElementConfig.java | 5 + .../ModelEngineBlockEntityElementConfig.java | 5 + .../ItemDisplayBlockEntityElement.java | 18 ++- .../ItemDisplayBlockEntityElementConfig.java | 13 ++ .../TextDisplayBlockEntityElement.java | 22 +++- .../TextDisplayBlockEntityElementConfig.java | 13 ++ .../plugin/injector/WorldStorageInjector.java | 14 ++- .../render/ConstantBlockEntityRenderer.java | 22 +++- .../render/element/BlockEntityElement.java | 2 + .../element/BlockEntityElementConfig.java | 9 ++ .../craftengine/core/world/chunk/CEChunk.java | 116 ++++++++++++++++-- 11 files changed, 211 insertions(+), 28 deletions(-) diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelBlockEntityElementConfig.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelBlockEntityElementConfig.java index 0b31cf939..7127e4966 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelBlockEntityElementConfig.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelBlockEntityElementConfig.java @@ -44,6 +44,11 @@ public class BetterModelBlockEntityElementConfig implements BlockEntityElementCo return new BetterModelBlockEntityElement(world, pos, this); } + @Override + public Class elementClass() { + return BetterModelBlockEntityElement.class; + } + public static class Factory implements BlockEntityElementConfigFactory { @SuppressWarnings("unchecked") diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/modelengine/ModelEngineBlockEntityElementConfig.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/modelengine/ModelEngineBlockEntityElementConfig.java index a8dbd2643..0a4c5c41c 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/modelengine/ModelEngineBlockEntityElementConfig.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/modelengine/ModelEngineBlockEntityElementConfig.java @@ -44,6 +44,11 @@ public class ModelEngineBlockEntityElementConfig implements BlockEntityElementCo return new ModelEngineBlockEntityElement(world, pos, this); } + @Override + public Class elementClass() { + return ModelEngineBlockEntityElement.class; + } + public static class Factory implements BlockEntityElementConfigFactory { @SuppressWarnings("unchecked") diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElement.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElement.java index 074bc87c5..1f4760aef 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElement.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElement.java @@ -13,13 +13,16 @@ import java.util.List; import java.util.UUID; public class ItemDisplayBlockEntityElement implements BlockEntityElement { - private final ItemDisplayBlockEntityElementConfig config; - private final Object cachedSpawnPacket; - private final Object cachedDespawnPacket; - private final int entityId; + public final ItemDisplayBlockEntityElementConfig config; + public final Object cachedSpawnPacket; + public final Object cachedDespawnPacket; + public final int entityId; public ItemDisplayBlockEntityElement(ItemDisplayBlockEntityElementConfig config, BlockPos pos) { - int entityId = CoreReflections.instance$Entity$ENTITY_COUNTER.incrementAndGet(); + this(config, pos, CoreReflections.instance$Entity$ENTITY_COUNTER.incrementAndGet()); + } + + public ItemDisplayBlockEntityElement(ItemDisplayBlockEntityElementConfig config, BlockPos pos, int entityId) { Vector3f position = config.position(); this.cachedSpawnPacket = FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( entityId, UUID.randomUUID(), pos.x() + position.x, pos.y() + position.y, pos.z() + position.z, @@ -39,4 +42,9 @@ public class ItemDisplayBlockEntityElement implements BlockEntityElement { public void show(Player player) { player.sendPackets(List.of(this.cachedSpawnPacket, FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player))), true); } + + @Override + public void transform(Player player) { + player.sendPacket(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player)), false); + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElementConfig.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElementConfig.java index 53320d84d..5fc5a399c 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElementConfig.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElementConfig.java @@ -78,6 +78,19 @@ public class ItemDisplayBlockEntityElementConfig implements BlockEntityElementCo return new ItemDisplayBlockEntityElement(this, pos); } + @Override + public ItemDisplayBlockEntityElement create(World world, BlockPos pos, ItemDisplayBlockEntityElement previous) { + if (previous.config.yRot != this.yRot || !previous.config.position.equals(this.position)) { + return null; + } + return new ItemDisplayBlockEntityElement(this, pos, previous.entityId); + } + + @Override + public Class elementClass() { + return ItemDisplayBlockEntityElement.class; + } + public Item item(Player player) { return this.item.apply(player); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElement.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElement.java index 45a1c6c9d..b0d604745 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElement.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElement.java @@ -13,13 +13,16 @@ import java.util.List; import java.util.UUID; public class TextDisplayBlockEntityElement implements BlockEntityElement { - private final TextDisplayBlockEntityElementConfig config; - private final Object cachedSpawnPacket; - private final Object cachedDespawnPacket; - private final int entityId; + public final TextDisplayBlockEntityElementConfig config; + public final Object cachedSpawnPacket; + public final Object cachedDespawnPacket; + public final int entityId; public TextDisplayBlockEntityElement(TextDisplayBlockEntityElementConfig config, BlockPos pos) { - int entityId = CoreReflections.instance$Entity$ENTITY_COUNTER.incrementAndGet(); + this(config, pos, CoreReflections.instance$Entity$ENTITY_COUNTER.incrementAndGet()); + } + + public TextDisplayBlockEntityElement(TextDisplayBlockEntityElementConfig config, BlockPos pos, int entityId) { Vector3f position = config.position(); this.cachedSpawnPacket = FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( entityId, UUID.randomUUID(), pos.x() + position.x, pos.y() + position.y, pos.z() + position.z, @@ -39,4 +42,13 @@ public class TextDisplayBlockEntityElement implements BlockEntityElement { public void show(Player player) { player.sendPackets(List.of(this.cachedSpawnPacket, FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player))), true); } + + @Override + public void transform(Player player) { + player.sendPacket(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player)), false); + } + + public int entityId() { + return entityId; + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElementConfig.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElementConfig.java index e707023ee..eaef23d0b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElementConfig.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElementConfig.java @@ -66,6 +66,19 @@ public class TextDisplayBlockEntityElementConfig implements BlockEntityElementCo return new TextDisplayBlockEntityElement(this, pos); } + @Override + public TextDisplayBlockEntityElement create(World world, BlockPos pos, TextDisplayBlockEntityElement previous) { + if (previous.config.yRot != this.yRot || !previous.config.position.equals(this.position)) { + return null; + } + return new TextDisplayBlockEntityElement(this, pos, previous.entityId); + } + + @Override + public Class elementClass() { + return TextDisplayBlockEntityElement.class; + } + public Component text(Player player) { return AdventureHelper.miniMessage().deserialize(this.text, PlayerOptionalContext.of(player).tagResolvers()); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/WorldStorageInjector.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/WorldStorageInjector.java index b1e7d7ff1..59ec1b225 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/WorldStorageInjector.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/WorldStorageInjector.java @@ -19,6 +19,8 @@ import net.momirealms.craftengine.core.block.DelegatingBlockState; import net.momirealms.craftengine.core.block.EmptyBlock; import net.momirealms.craftengine.core.block.ImmutableBlockState; import net.momirealms.craftengine.core.block.entity.BlockEntity; +import net.momirealms.craftengine.core.block.entity.render.ConstantBlockEntityRenderer; +import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.util.ReflectionUtils; @@ -226,7 +228,10 @@ public final class WorldStorageInjector { // 处理 自定义块到自定义块或原版块到自定义块 CEChunk chunk = holder.ceChunk(); chunk.setDirty(true); + + ConstantBlockEntityRenderer previousRenderer = null; // 如果两个方块没有相同的主人 且 旧方块有方块实体 + if (!previousImmutableBlockState.isEmpty()) { if (previousImmutableBlockState.owner() != newImmutableBlockState.owner() && previousImmutableBlockState.hasBlockEntity()) { BlockPos pos = new BlockPos(chunk.chunkPos.x * 16 + x, section.sectionY * 16 + y, chunk.chunkPos.z * 16 + z); @@ -242,9 +247,11 @@ public final class WorldStorageInjector { } if (previousImmutableBlockState.hasConstantBlockEntityRenderer()) { BlockPos pos = new BlockPos(chunk.chunkPos.x * 16 + x, section.sectionY * 16 + y, chunk.chunkPos.z * 16 + z); - chunk.removeConstantBlockEntityRenderer(pos); + // 如果新状态没有entity renderer,那么直接移除,否则暂存 + previousRenderer = chunk.removeConstantBlockEntityRenderer(pos, !newImmutableBlockState.hasConstantBlockEntityRenderer()); } } + if (newImmutableBlockState.hasBlockEntity()) { BlockPos pos = new BlockPos(chunk.chunkPos.x * 16 + x, section.sectionY * 16 + y, chunk.chunkPos.z * 16 + z); BlockEntity blockEntity = chunk.getBlockEntity(pos, false); @@ -264,10 +271,13 @@ public final class WorldStorageInjector { chunk.createDynamicBlockEntityRenderer(blockEntity); } } + + // 处理新老entity renderer更替 if (newImmutableBlockState.hasConstantBlockEntityRenderer()) { BlockPos pos = new BlockPos(chunk.chunkPos.x * 16 + x, section.sectionY * 16 + y, chunk.chunkPos.z * 16 + z); - chunk.addConstantBlockEntityRenderer(pos, newImmutableBlockState); + chunk.addConstantBlockEntityRenderer(pos, newImmutableBlockState, previousRenderer); } + // 如果新方块的光照属性和客户端认为的不同 if (Config.enableLightSystem()) { if (previousImmutableBlockState.isEmpty()) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/ConstantBlockEntityRenderer.java b/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/ConstantBlockEntityRenderer.java index f28ab579f..82c9fdeae 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/ConstantBlockEntityRenderer.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/ConstantBlockEntityRenderer.java @@ -4,6 +4,8 @@ import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityEl import net.momirealms.craftengine.core.entity.player.Player; import org.jetbrains.annotations.ApiStatus; +import java.util.Collection; + @ApiStatus.Experimental public class ConstantBlockEntityRenderer { private final BlockEntityElement[] elements; @@ -14,25 +16,37 @@ public class ConstantBlockEntityRenderer { public void show(Player player) { for (BlockEntityElement element : this.elements) { - element.show(player); + if (element != null) { + element.show(player); + } } } public void hide(Player player) { for (BlockEntityElement element : this.elements) { - element.hide(player); + if (element != null) { + element.hide(player); + } } } public void deactivate() { for (BlockEntityElement element : this.elements) { - element.deactivate(); + if (element != null) { + element.deactivate(); + } } } public void activate() { for (BlockEntityElement element : this.elements) { - element.activate(); + if (element != null) { + element.activate(); + } } } + + public BlockEntityElement[] elements() { + return this.elements; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/element/BlockEntityElement.java b/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/element/BlockEntityElement.java index eaf5d605c..a0c0fb321 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/element/BlockEntityElement.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/element/BlockEntityElement.java @@ -10,6 +10,8 @@ public interface BlockEntityElement { void hide(Player player); + default void transform(Player player) {} + default void deactivate() {} default void activate() {} diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/element/BlockEntityElementConfig.java b/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/element/BlockEntityElementConfig.java index a61f0b030..c5c0f59db 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/element/BlockEntityElementConfig.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/element/BlockEntityElementConfig.java @@ -3,7 +3,16 @@ package net.momirealms.craftengine.core.block.entity.render.element; import net.momirealms.craftengine.core.world.BlockPos; import net.momirealms.craftengine.core.world.World; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + public interface BlockEntityElementConfig { E create(World world, BlockPos pos); + + default E create(World world, BlockPos pos, E previous) { + return null; + } + + Class elementClass(); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java index d48e09472..67e355a05 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java @@ -12,6 +12,7 @@ import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityEl import net.momirealms.craftengine.core.block.entity.tick.*; import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.plugin.logger.Debugger; +import net.momirealms.craftengine.core.util.BlockEntityTickersList; import net.momirealms.craftengine.core.world.*; import net.momirealms.craftengine.core.world.chunk.serialization.DefaultBlockEntityRendererSerializer; import net.momirealms.craftengine.core.world.chunk.serialization.DefaultBlockEntitySerializer; @@ -115,40 +116,131 @@ public class CEChunk { } } - public void addConstantBlockEntityRenderer(BlockPos pos) { - this.addConstantBlockEntityRenderer(pos, this.getBlockState(pos)); + public ConstantBlockEntityRenderer addConstantBlockEntityRenderer(BlockPos pos) { + return this.addConstantBlockEntityRenderer(pos, this.getBlockState(pos), null); } - public void addConstantBlockEntityRenderer(BlockPos pos, ImmutableBlockState state) { + public ConstantBlockEntityRenderer addConstantBlockEntityRenderer(BlockPos pos, ImmutableBlockState state) { + return this.addConstantBlockEntityRenderer(pos, state, null); + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + public ConstantBlockEntityRenderer addConstantBlockEntityRenderer(BlockPos pos, ImmutableBlockState state, @Nullable ConstantBlockEntityRenderer previous) { BlockEntityElementConfig[] renderers = state.constantRenderers(); if (renderers != null && renderers.length > 0) { BlockEntityElement[] elements = new BlockEntityElement[renderers.length]; - World wrappedWorld = this.world.world(); - for (int i = 0; i < elements.length; i++) { - elements[i] = renderers[i].create(wrappedWorld, pos); - } ConstantBlockEntityRenderer renderer = new ConstantBlockEntityRenderer(elements); - for (Player player : getTrackedBy()) { - renderer.show(player); + World wrappedWorld = this.world.world(); + List trackedBy = getTrackedBy(); + boolean hasTrackedBy = trackedBy != null && !trackedBy.isEmpty(); + // 处理旧到新的转换 + if (previous != null) { + // 由于entity-render的体量基本都很小,所以考虑一个特殊情况,即前后都是1个renderer,对此情况进行简化和优化 + BlockEntityElement[] previousElements = previous.elements().clone(); + if (previousElements.length == 1 && renderers.length == 1) { + BlockEntityElement previousElement = previousElements[0]; + BlockEntityElementConfig config = renderers[0]; + outer: { + if (config.elementClass().isInstance(previousElement)) { + BlockEntityElement element = ((BlockEntityElementConfig) config).create(wrappedWorld, pos, previousElement); + if (element != null) { + elements[0] = element; + if (hasTrackedBy) { + for (Player player : trackedBy) { + element.transform(player); + } + } + break outer; + } + } + BlockEntityElement element = config.create(wrappedWorld, pos); + elements[0] = element; + if (hasTrackedBy) { + for (Player player : trackedBy) { + previousElement.hide(player); + element.show(player); + } + } + } + } else { + outer: for (int i = 0; i < elements.length; i++) { + BlockEntityElementConfig config = renderers[i]; + { + for (int j = 0; j < previousElements.length; j++) { + BlockEntityElement previousElement = previousElements[j]; + if (previousElement != null && config.elementClass().isInstance(previousElement)) { + BlockEntityElement newElement = ((BlockEntityElementConfig) config).create(wrappedWorld, pos, previousElement); + if (newElement != null) { + previousElements[i] = null; + elements[i] = newElement; + if (hasTrackedBy) { + for (Player player : trackedBy) { + newElement.transform(player); + } + } + continue outer; + } + } + } + BlockEntityElement newElement = config.create(wrappedWorld, pos); + elements[i] = newElement; + if (hasTrackedBy) { + for (Player player : trackedBy) { + newElement.show(player); + } + } + } + } + if (hasTrackedBy) { + for (int i = 0; i < previousElements.length; i++) { + BlockEntityElement previousElement = previousElements[i]; + if (previousElement != null) { + for (Player player : trackedBy) { + previousElement.hide(player); + } + } + } + } + } + } else { + for (int i = 0; i < elements.length; i++) { + elements[i] = renderers[i].create(wrappedWorld, pos); + } + if (hasTrackedBy) { + for (Player player : trackedBy) { + renderer.show(player); + } + } } try { this.renderLock.writeLock().lock(); this.constantBlockEntityRenderers.put(pos, renderer); + return renderer; } finally { this.renderLock.writeLock().unlock(); } } + return null; } - public void removeConstantBlockEntityRenderer(BlockPos pos) { + @Nullable + public ConstantBlockEntityRenderer removeConstantBlockEntityRenderer(BlockPos pos) { + return this.removeConstantBlockEntityRenderer(pos, true); + } + + @Nullable + public ConstantBlockEntityRenderer removeConstantBlockEntityRenderer(BlockPos pos, boolean hide) { try { this.renderLock.writeLock().lock(); ConstantBlockEntityRenderer removed = this.constantBlockEntityRenderers.remove(pos); if (removed != null) { - for (Player player : getTrackedBy()) { - removed.hide(player); + if (hide) { + for (Player player : getTrackedBy()) { + removed.hide(player); + } } } + return removed; } finally { this.renderLock.writeLock().unlock(); } From c64cc974a6880a5344a854a8f0feb4ddf65ec4e8 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Tue, 4 Nov 2025 22:14:00 +0800 Subject: [PATCH 08/37] =?UTF-8?q?=E6=B8=85=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/plugin/injector/WorldStorageInjector.java | 1 - .../core/block/entity/render/ConstantBlockEntityRenderer.java | 2 -- .../block/entity/render/element/BlockEntityElementConfig.java | 3 --- .../momirealms/craftengine/core/pack/AbstractPackManager.java | 1 - .../net/momirealms/craftengine/core/world/chunk/CEChunk.java | 1 - 5 files changed, 8 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/WorldStorageInjector.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/WorldStorageInjector.java index 59ec1b225..fd65f8003 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/WorldStorageInjector.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/WorldStorageInjector.java @@ -20,7 +20,6 @@ import net.momirealms.craftengine.core.block.EmptyBlock; import net.momirealms.craftengine.core.block.ImmutableBlockState; import net.momirealms.craftengine.core.block.entity.BlockEntity; import net.momirealms.craftengine.core.block.entity.render.ConstantBlockEntityRenderer; -import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.util.ReflectionUtils; diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/ConstantBlockEntityRenderer.java b/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/ConstantBlockEntityRenderer.java index 82c9fdeae..4b45900a0 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/ConstantBlockEntityRenderer.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/ConstantBlockEntityRenderer.java @@ -4,8 +4,6 @@ import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityEl import net.momirealms.craftengine.core.entity.player.Player; import org.jetbrains.annotations.ApiStatus; -import java.util.Collection; - @ApiStatus.Experimental public class ConstantBlockEntityRenderer { private final BlockEntityElement[] elements; diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/element/BlockEntityElementConfig.java b/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/element/BlockEntityElementConfig.java index c5c0f59db..0d3c320ad 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/element/BlockEntityElementConfig.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/element/BlockEntityElementConfig.java @@ -3,9 +3,6 @@ package net.momirealms.craftengine.core.block.entity.render.element; import net.momirealms.craftengine.core.world.BlockPos; import net.momirealms.craftengine.core.world.World; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; - public interface BlockEntityElementConfig { E create(World world, BlockPos pos); diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java index 8f165a669..776829a2f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java @@ -43,7 +43,6 @@ import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.scanner.ScannerException; import javax.imageio.ImageIO; -import javax.imageio.ImageReader; import java.awt.image.BufferedImage; import java.io.*; import java.nio.charset.StandardCharsets; diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java index 67e355a05..05a04829e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java @@ -12,7 +12,6 @@ import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityEl import net.momirealms.craftengine.core.block.entity.tick.*; import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.plugin.logger.Debugger; -import net.momirealms.craftengine.core.util.BlockEntityTickersList; import net.momirealms.craftengine.core.world.*; import net.momirealms.craftengine.core.world.chunk.serialization.DefaultBlockEntityRendererSerializer; import net.momirealms.craftengine.core.world.chunk.serialization.DefaultBlockEntitySerializer; From ee21a0eb3509603a4f772c23e0ecb1af6a5ad482 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Tue, 4 Nov 2025 22:37:23 +0800 Subject: [PATCH 09/37] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=8B=E5=BA=A7?= =?UTF-8?q?=E6=A4=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/entity/seat/BukkitSeatManager.java | 4 +- .../craftengine/bukkit/util/EntityUtils.java | 50 ++++++++++--------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/seat/BukkitSeatManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/seat/BukkitSeatManager.java index 9ebc9577f..9e45aa593 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/seat/BukkitSeatManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/seat/BukkitSeatManager.java @@ -113,9 +113,9 @@ public class BukkitSeatManager implements SeatManager { if (!isSeat) return; Location location = seat.getLocation(); if (seat instanceof ArmorStand) { - location.add(0, 0.9875,0); + location.add(0, 0.3875,0); } else { - location.add(0,0.25,0); + location.add(0,-0.35,0); } seat.remove(); EntityUtils.safeDismount(player, location); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java index ec227f9cd..05a9600e1 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java @@ -63,32 +63,34 @@ public final class EntityUtils { BlockPos pos = new BlockPos(MiscUtils.fastFloor(x), MiscUtils.fastFloor(y), MiscUtils.fastFloor(z)); try { double floorHeight = (double) CoreReflections.method$BlockGetter$getBlockFloorHeight.invoke(serverLevel, LocationUtils.toBlockPos(pos)); - if (pos.y() + floorHeight > y + 0.75) { + if (pos.y() + floorHeight > y + 0.75 || !isBlockFloorValid(floorHeight)) { + floorHeight = (double) CoreReflections.method$BlockGetter$getBlockFloorHeight.invoke(serverLevel, LocationUtils.toBlockPos(pos.below())); + if (pos.y() + floorHeight - 1 < y - 0.75 || !isBlockFloorValid(floorHeight)) { + continue; + } + floorHeight -= 1; + } + Object aabb = CoreReflections.method$LivingEntity$getLocalBoundsForPose.invoke(serverPlayer, pose); + Object vec3 = FastNMS.INSTANCE.constructor$Vec3(x, pos.y() + floorHeight, z); + Object newAABB = FastNMS.INSTANCE.method$AABB$move(aabb, vec3); + boolean canDismount = (boolean) CoreReflections.method$DismountHelper$canDismountTo0.invoke(null, serverLevel, serverPlayer, newAABB); + if (!canDismount) { continue; } - if (isBlockFloorValid(floorHeight)) { - Object aabb = CoreReflections.method$LivingEntity$getLocalBoundsForPose.invoke(serverPlayer, pose); - Object vec3 = FastNMS.INSTANCE.constructor$Vec3(x, pos.y() + floorHeight, z); - Object newAABB = FastNMS.INSTANCE.method$AABB$move(aabb, vec3); - boolean canDismount = (boolean) CoreReflections.method$DismountHelper$canDismountTo0.invoke(null, serverLevel, serverPlayer, newAABB); - if (!canDismount) { - continue; - } - if (!FastNMS.INSTANCE.checkEntityCollision(serverLevel, List.of(newAABB))) { - continue; - } - if (VersionHelper.isFolia()) { - player.teleportAsync(new Location(player.getWorld(), x, pos.y() + floorHeight, z, player.getYaw(), player.getPitch())); - } else { - player.teleport(new Location(player.getWorld(), x, pos.y() + floorHeight, z, player.getYaw(), player.getPitch())); - } - if (pose == CoreReflections.instance$Pose$STANDING) { - player.setPose(Pose.STANDING); - } else if (pose == CoreReflections.instance$Pose$CROUCHING) { - player.setPose(Pose.SNEAKING); - } else if (pose == CoreReflections.instance$Pose$SWIMMING) { - player.setPose(Pose.SWIMMING); - } + if (!FastNMS.INSTANCE.checkEntityCollision(serverLevel, List.of(newAABB))) { + continue; + } + if (VersionHelper.isFolia()) { + player.teleportAsync(new Location(player.getWorld(), x, pos.y() + floorHeight, z, player.getYaw(), player.getPitch())); + } else { + player.teleport(new Location(player.getWorld(), x, pos.y() + floorHeight, z, player.getYaw(), player.getPitch())); + } + if (pose == CoreReflections.instance$Pose$STANDING) { + player.setPose(Pose.STANDING); + } else if (pose == CoreReflections.instance$Pose$CROUCHING) { + player.setPose(Pose.SNEAKING); + } else if (pose == CoreReflections.instance$Pose$SWIMMING) { + player.setPose(Pose.SWIMMING); } } catch (ReflectiveOperationException e) { throw new RuntimeException(e); From 763800e331779a7318ade65e41bdd0736b5df028 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Tue, 4 Nov 2025 23:09:43 +0800 Subject: [PATCH 10/37] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=96=B9=E5=9D=97=E5=AE=9E=E4=BD=93=E6=B8=B2=E6=9F=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../element/ItemDisplayBlockEntityElement.java | 14 +++++++++++--- .../ItemDisplayBlockEntityElementConfig.java | 5 +---- .../element/TextDisplayBlockEntityElement.java | 14 +++++++++++--- .../TextDisplayBlockEntityElementConfig.java | 5 +---- gradle.properties | 2 +- 5 files changed, 25 insertions(+), 15 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElement.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElement.java index 1f4760aef..ddb1926cb 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElement.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElement.java @@ -16,13 +16,14 @@ public class ItemDisplayBlockEntityElement implements BlockEntityElement { public final ItemDisplayBlockEntityElementConfig config; public final Object cachedSpawnPacket; public final Object cachedDespawnPacket; + public final Object cachedUpdatePosPacket; public final int entityId; public ItemDisplayBlockEntityElement(ItemDisplayBlockEntityElementConfig config, BlockPos pos) { - this(config, pos, CoreReflections.instance$Entity$ENTITY_COUNTER.incrementAndGet()); + this(config, pos, CoreReflections.instance$Entity$ENTITY_COUNTER.incrementAndGet(), false); } - public ItemDisplayBlockEntityElement(ItemDisplayBlockEntityElementConfig config, BlockPos pos, int entityId) { + public ItemDisplayBlockEntityElement(ItemDisplayBlockEntityElementConfig config, BlockPos pos, int entityId, boolean posChanged) { Vector3f position = config.position(); this.cachedSpawnPacket = FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( entityId, UUID.randomUUID(), pos.x() + position.x, pos.y() + position.y, pos.z() + position.z, @@ -31,6 +32,7 @@ public class ItemDisplayBlockEntityElement implements BlockEntityElement { this.config = config; this.cachedDespawnPacket = FastNMS.INSTANCE.constructor$ClientboundRemoveEntitiesPacket(IntList.of(entityId)); this.entityId = entityId; + this.cachedUpdatePosPacket = posChanged ? FastNMS.INSTANCE.constructor$ClientboundEntityPositionSyncPacket(this.entityId, pos.x() + position.x, pos.y() + position.y, pos.z() + position.z, config.yRot(), config.xRot(), false) : null; } @Override @@ -45,6 +47,12 @@ public class ItemDisplayBlockEntityElement implements BlockEntityElement { @Override public void transform(Player player) { - player.sendPacket(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player)), false); + if (this.cachedUpdatePosPacket != null) { + player.sendPackets(List.of( + FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player)), + this.cachedUpdatePosPacket), false); + } else { + player.sendPacket(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player)), false); + } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElementConfig.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElementConfig.java index 5fc5a399c..3414f1988 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElementConfig.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElementConfig.java @@ -80,10 +80,7 @@ public class ItemDisplayBlockEntityElementConfig implements BlockEntityElementCo @Override public ItemDisplayBlockEntityElement create(World world, BlockPos pos, ItemDisplayBlockEntityElement previous) { - if (previous.config.yRot != this.yRot || !previous.config.position.equals(this.position)) { - return null; - } - return new ItemDisplayBlockEntityElement(this, pos, previous.entityId); + return new ItemDisplayBlockEntityElement(this, pos, previous.entityId, previous.config.yRot != this.yRot || !previous.config.position.equals(this.position)); } @Override diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElement.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElement.java index b0d604745..5990c5a42 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElement.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElement.java @@ -16,13 +16,14 @@ public class TextDisplayBlockEntityElement implements BlockEntityElement { public final TextDisplayBlockEntityElementConfig config; public final Object cachedSpawnPacket; public final Object cachedDespawnPacket; + public final Object cachedUpdatePosPacket; public final int entityId; public TextDisplayBlockEntityElement(TextDisplayBlockEntityElementConfig config, BlockPos pos) { - this(config, pos, CoreReflections.instance$Entity$ENTITY_COUNTER.incrementAndGet()); + this(config, pos, CoreReflections.instance$Entity$ENTITY_COUNTER.incrementAndGet(), false); } - public TextDisplayBlockEntityElement(TextDisplayBlockEntityElementConfig config, BlockPos pos, int entityId) { + public TextDisplayBlockEntityElement(TextDisplayBlockEntityElementConfig config, BlockPos pos, int entityId, boolean posChanged) { Vector3f position = config.position(); this.cachedSpawnPacket = FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( entityId, UUID.randomUUID(), pos.x() + position.x, pos.y() + position.y, pos.z() + position.z, @@ -31,6 +32,7 @@ public class TextDisplayBlockEntityElement implements BlockEntityElement { this.config = config; this.cachedDespawnPacket = FastNMS.INSTANCE.constructor$ClientboundRemoveEntitiesPacket(IntList.of(entityId)); this.entityId = entityId; + this.cachedUpdatePosPacket = posChanged ? FastNMS.INSTANCE.constructor$ClientboundEntityPositionSyncPacket(this.entityId, pos.x() + position.x, pos.y() + position.y, pos.z() + position.z, config.yRot(), config.xRot(), false) : null; } @Override @@ -45,7 +47,13 @@ public class TextDisplayBlockEntityElement implements BlockEntityElement { @Override public void transform(Player player) { - player.sendPacket(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player)), false); + if (this.cachedUpdatePosPacket != null) { + player.sendPackets(List.of( + FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player)), + this.cachedUpdatePosPacket), false); + } else { + player.sendPacket(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player)), false); + } } public int entityId() { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElementConfig.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElementConfig.java index eaef23d0b..9156d7d4b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElementConfig.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElementConfig.java @@ -68,10 +68,7 @@ public class TextDisplayBlockEntityElementConfig implements BlockEntityElementCo @Override public TextDisplayBlockEntityElement create(World world, BlockPos pos, TextDisplayBlockEntityElement previous) { - if (previous.config.yRot != this.yRot || !previous.config.position.equals(this.position)) { - return null; - } - return new TextDisplayBlockEntityElement(this, pos, previous.entityId); + return new TextDisplayBlockEntityElement(this, pos, previous.entityId, previous.config.yRot != this.yRot || !previous.config.position.equals(this.position)); } @Override diff --git a/gradle.properties b/gradle.properties index 95f82a8aa..62d61a0aa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -49,7 +49,7 @@ byte_buddy_version=1.17.8 ahocorasick_version=0.6.3 snake_yaml_version=2.5 anti_grief_version=1.0.4 -nms_helper_version=1.0.123 +nms_helper_version=1.0.124 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.34.5 From 625718c70469d572a73720b4c025f31aaa52756a Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Wed, 5 Nov 2025 19:45:01 +0800 Subject: [PATCH 11/37] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=8C=85=E5=8F=91?= =?UTF-8?q?=E9=80=81=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../renderer/element/ItemDisplayBlockEntityElement.java | 4 +--- .../renderer/element/TextDisplayBlockEntityElement.java | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElement.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElement.java index ddb1926cb..4159f41d7 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElement.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElement.java @@ -48,9 +48,7 @@ public class ItemDisplayBlockEntityElement implements BlockEntityElement { @Override public void transform(Player player) { if (this.cachedUpdatePosPacket != null) { - player.sendPackets(List.of( - FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player)), - this.cachedUpdatePosPacket), false); + player.sendPackets(List.of(this.cachedUpdatePosPacket, FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player))), false); } else { player.sendPacket(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player)), false); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElement.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElement.java index 5990c5a42..de3c7a644 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElement.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElement.java @@ -48,9 +48,7 @@ public class TextDisplayBlockEntityElement implements BlockEntityElement { @Override public void transform(Player player) { if (this.cachedUpdatePosPacket != null) { - player.sendPackets(List.of( - FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player)), - this.cachedUpdatePosPacket), false); + player.sendPackets(List.of(this.cachedUpdatePosPacket, FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player))), false); } else { player.sendPacket(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player)), false); } From d327eecc5e3e1aea326393b4404ba7a117cc24a6 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Wed, 5 Nov 2025 23:05:19 +0800 Subject: [PATCH 12/37] =?UTF-8?q?=E6=B3=A8=E5=85=A5=E5=8C=BA=E5=9D=97?= =?UTF-8?q?=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LegacySlimeWorldDataStorage.java | 15 ++++++ .../slimeworld/SlimeWorldDataStorage.java | 20 +++++-- .../reflection/minecraft/CoreReflections.java | 15 +++++- .../bukkit/world/BukkitWorldManager.java | 54 ++++++++++++++++--- .../craftengine/core/world/chunk/CEChunk.java | 15 +++--- .../world/chunk/storage/CachedStorage.java | 11 ++++ .../storage/DefaultRegionFileStorage.java | 18 +++++++ .../world/chunk/storage/WorldDataStorage.java | 7 +++ gradle.properties | 2 +- 9 files changed, 139 insertions(+), 18 deletions(-) diff --git a/bukkit/compatibility/legacy/src/main/java/net/momirealms/craftengine/bukkit/compatibility/legacy/slimeworld/LegacySlimeWorldDataStorage.java b/bukkit/compatibility/legacy/src/main/java/net/momirealms/craftengine/bukkit/compatibility/legacy/slimeworld/LegacySlimeWorldDataStorage.java index 4feff8a93..f62ac011f 100644 --- a/bukkit/compatibility/legacy/src/main/java/net/momirealms/craftengine/bukkit/compatibility/legacy/slimeworld/LegacySlimeWorldDataStorage.java +++ b/bukkit/compatibility/legacy/src/main/java/net/momirealms/craftengine/bukkit/compatibility/legacy/slimeworld/LegacySlimeWorldDataStorage.java @@ -26,6 +26,14 @@ public class LegacySlimeWorldDataStorage implements WorldDataStorage { return slimeWorld.get(); } + @Override + public CEChunk readNewChunkAt(CEWorld world, ChunkPos pos) { + SlimeChunk slimeChunk = getWorld().getChunk(pos.x, pos.z); + if (slimeChunk == null) return new CEChunk(world, pos); + slimeChunk.getExtraData().getValue().remove("craftengine"); + return new CEChunk(world, pos); + } + @Override public @NotNull CEChunk readChunkAt(@NotNull CEWorld world, @NotNull ChunkPos pos) { SlimeChunk slimeChunk = getWorld().getChunk(pos.x, pos.z); @@ -57,6 +65,13 @@ public class LegacySlimeWorldDataStorage implements WorldDataStorage { } } + @Override + public void clearChunkAt(@NotNull ChunkPos pos) { + SlimeChunk slimeChunk = getWorld().getChunk(pos.x, pos.z); + if (slimeChunk == null) return; + slimeChunk.getExtraData().getValue().remove("craftengine"); + } + @Override public void flush() { } diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/slimeworld/SlimeWorldDataStorage.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/slimeworld/SlimeWorldDataStorage.java index 663689520..6b5f519c9 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/slimeworld/SlimeWorldDataStorage.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/slimeworld/SlimeWorldDataStorage.java @@ -27,6 +27,14 @@ public class SlimeWorldDataStorage implements WorldDataStorage { return slimeWorld.get(); } + @Override + public CEChunk readNewChunkAt(CEWorld world, ChunkPos pos) { + SlimeChunk slimeChunk = getWorld().getChunk(pos.x, pos.z); + if (slimeChunk == null) return new CEChunk(world, pos); + slimeChunk.getExtraData().remove("craftengine"); + return new CEChunk(world, pos); + } + @Override public @NotNull CEChunk readChunkAt(@NotNull CEWorld world, @NotNull ChunkPos pos) { SlimeChunk slimeChunk = getWorld().getChunk(pos.x, pos.z); @@ -42,7 +50,7 @@ public class SlimeWorldDataStorage implements WorldDataStorage { } } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) @Override public void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk) { SlimeChunk slimeChunk = getWorld().getChunk(pos.x, pos.z); @@ -53,8 +61,7 @@ public class SlimeWorldDataStorage implements WorldDataStorage { } else { try { Object tag = adaptor.bytesToByteArrayTag(NBT.toBytes(nbt)); - Map data1 = slimeChunk.getExtraData(); - Map data2 = (Map) data1; + Map data2 = (Map) slimeChunk.getExtraData(); data2.put("craftengine", tag); } catch (Exception e) { throw new RuntimeException("Failed to write chunk tag to slime world. " + pos, e); @@ -62,6 +69,13 @@ public class SlimeWorldDataStorage implements WorldDataStorage { } } + @Override + public void clearChunkAt(@NotNull ChunkPos pos) { + SlimeChunk slimeChunk = getWorld().getChunk(pos.x, pos.z); + if (slimeChunk == null) return; + slimeChunk.getExtraData().remove("craftengine"); + } + @Override public void flush() { } 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 c5beafe9e..3931bdbd3 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 @@ -3135,7 +3135,8 @@ public final class CoreReflections { public static final Class clazz$ChunkMap = requireNonNull( BukkitReflectionUtils.findReobfOrMojmapClass( "server.level.PlayerChunkMap", - "server.level.ChunkMap" + "server.level.PlayerChunkMap" // paper remap的问题,所以使用旧mapping +// "server.level.ChunkMap" ) ); @@ -4536,4 +4537,16 @@ public final class CoreReflections { public static final Method method$DismountHelper$canDismountTo1 = requireNonNull( ReflectionUtils.getStaticMethod(clazz$DismountHelper, boolean.class, clazz$CollisionGetter, clazz$Vec3, clazz$LivingEntity, clazz$Pose) ); + + public static final Class clazz$WorldGenContext = MiscUtils.requireNonNullIf( + ReflectionUtils.getClazz(BukkitReflectionUtils.assembleMCClass("world.level.chunk.status.WorldGenContext")), VersionHelper.isOrAbove1_20_5() + ); + + public static final Field field$ChunkMap$worldGenContext = MiscUtils.requireNonNullIf( + ReflectionUtils.getDeclaredField(clazz$ChunkMap, clazz$WorldGenContext, 0), VersionHelper.isOrAbove1_20_5() + ); + + public static final Field field$ChunkMap$chunkGenerator = MiscUtils.requireNonNullIf( + ReflectionUtils.getDeclaredField(clazz$ChunkMap, clazz$ChunkGenerator, 0), !VersionHelper.isOrAbove1_20_5() + ); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldManager.java index ea4ab38e3..ba41c8181 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldManager.java @@ -92,10 +92,12 @@ public class BukkitWorldManager implements WorldManager, Listener { public void delayedInit() { // load loaded chunks for (World world : Bukkit.getWorlds()) { + BukkitWorld wrappedWorld = new BukkitWorld(world); try { - CEWorld ceWorld = this.worlds.computeIfAbsent(world.getUID(), k -> new BukkitCEWorld(new BukkitWorld(world), this.storageAdaptor)); + CEWorld ceWorld = this.worlds.computeIfAbsent(world.getUID(), k -> new BukkitCEWorld(wrappedWorld, this.storageAdaptor)); + injectChunkGenerator(ceWorld); for (Chunk chunk : world.getLoadedChunks()) { - handleChunkLoad(ceWorld, chunk); + handleChunkLoad(ceWorld, chunk, false); } ceWorld.setTicking(true); } catch (Exception e) { @@ -142,8 +144,9 @@ public class BukkitWorldManager implements WorldManager, Listener { CEWorld ceWorld = new BukkitCEWorld(world, this.storageAdaptor); this.worlds.put(uuid, ceWorld); this.resetWorldArray(); + this.injectChunkGenerator(ceWorld); for (Chunk chunk : ((World) world.platformWorld()).getLoadedChunks()) { - handleChunkLoad(ceWorld, chunk); + handleChunkLoad(ceWorld, chunk, false); } ceWorld.setTicking(true); } @@ -154,12 +157,20 @@ public class BukkitWorldManager implements WorldManager, Listener { if (this.worlds.containsKey(uuid)) return; this.worlds.put(uuid, world); this.resetWorldArray(); + this.injectChunkGenerator(world); for (Chunk chunk : ((World) world.world().platformWorld()).getLoadedChunks()) { - handleChunkLoad(world, chunk); + handleChunkLoad(world, chunk, false); } world.setTicking(true); } + private void injectChunkGenerator(CEWorld world) { + Object serverLevel = world.world.serverWorld(); + Object serverChunkCache = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(serverLevel); + Object chunkMap = FastNMS.INSTANCE.field$ServerChunkCache$chunkMap(serverChunkCache); + FastNMS.INSTANCE.injectedWorldGen(world, chunkMap); + } + @Override public CEWorld createWorld(net.momirealms.craftengine.core.world.World world, WorldDataStorage storage) { return new BukkitCEWorld(world, storage); @@ -219,7 +230,7 @@ public class BukkitWorldManager implements WorldManager, Listener { if (world == null) { return; } - handleChunkLoad(world, event.getChunk()); + handleChunkLoad(world, event.getChunk(), event.isNewChunk()); } @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) @@ -273,14 +284,42 @@ public class BukkitWorldManager implements WorldManager, Listener { FastNMS.INSTANCE.method$LevelChunk$markUnsaved(levelChunk); } ceChunk.unload(); + ceChunk.deactivateAllBlockEntities(); } } - private void handleChunkLoad(CEWorld ceWorld, Chunk chunk) { + public void handleChunkGenerate(CEWorld ceWorld, ChunkPos chunkPos, Object chunkAccess) { + Object[] sections = FastNMS.INSTANCE.method$ChunkAccess$getSections(chunkAccess); + CEChunk ceChunk; + try { + ceChunk = ceWorld.worldDataStorage().readNewChunkAt(ceWorld, chunkPos); + CESection[] ceSections = ceChunk.sections(); + synchronized (sections) { + for (int i = 0; i < ceSections.length; i++) { + CESection ceSection = ceSections[i]; + Object section = sections[i]; + int finalI = i; + WorldStorageInjector.injectLevelChunkSection(section, ceSection, ceChunk, new SectionPos(chunkPos.x, ceChunk.sectionY(i), chunkPos.z), + (injected) -> sections[finalI] = injected); + } + } + ceChunk.load(); + } catch (IOException e) { + this.plugin.logger().warn("Failed to read new chunk at " + chunkPos.x + " " + chunkPos.z, e); + } + } + + private void handleChunkLoad(CEWorld ceWorld, Chunk chunk, boolean isNew) { int chunkX = chunk.getX(); int chunkZ = chunk.getZ(); ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); - if (ceWorld.isChunkLoaded(chunkPos.longKey)) return; + CEChunk chunkAtIfLoaded = ceWorld.getChunkAtIfLoaded(chunkPos.longKey); + if (chunkAtIfLoaded != null) { + if (isNew) { + chunkAtIfLoaded.activateAllBlockEntities(); + } + return; + } CEChunk ceChunk; try { ceChunk = ceWorld.worldDataStorage().readChunkAt(ceWorld, chunkPos); @@ -382,5 +421,6 @@ public class BukkitWorldManager implements WorldManager, Listener { return; } ceChunk.load(); + ceChunk.activateAllBlockEntities(); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java index 05a04829e..960f54a8c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java @@ -35,6 +35,7 @@ public class CEChunk { private final ReentrantReadWriteLock renderLock = new ReentrantReadWriteLock(); private volatile boolean dirty; private volatile boolean loaded; + private volatile boolean activated; public CEChunk(CEWorld world, ChunkPos chunkPos) { this.world = world; @@ -274,7 +275,12 @@ public class CEChunk { this.removeDynamicBlockEntityRenderer(blockPos); } + public List getTrackedBy() { + return this.world.world.getTrackedBy(this.chunkPos); + } + public void activateAllBlockEntities() { + if (this.activated) return; for (BlockEntity blockEntity : this.blockEntities.values()) { blockEntity.setValid(true); this.replaceOrCreateTickingBlockEntity(blockEntity); @@ -283,13 +289,11 @@ public class CEChunk { for (ConstantBlockEntityRenderer renderer : this.constantBlockEntityRenderers.values()) { renderer.activate(); } - } - - public List getTrackedBy() { - return this.world.world.getTrackedBy(this.chunkPos); + this.activated = true; } public void deactivateAllBlockEntities() { + if (!this.activated) return; this.blockEntities.values().forEach(e -> e.setValid(false)); this.constantBlockEntityRenderers.values().forEach(ConstantBlockEntityRenderer::deactivate); this.dynamicBlockEntityRenderers.clear(); @@ -297,6 +301,7 @@ public class CEChunk { this.tickingSyncBlockEntitiesByPos.clear(); this.tickingAsyncBlockEntitiesByPos.values().forEach((ticker) -> ticker.setTicker(DummyTickingBlockEntity.INSTANCE)); this.tickingAsyncBlockEntitiesByPos.clear(); + this.activated = false; } @SuppressWarnings("unchecked") @@ -543,14 +548,12 @@ public class CEChunk { public void load() { if (this.loaded) return; this.world.addLoadedChunk(this); - this.activateAllBlockEntities(); this.loaded = true; } public void unload() { if (!this.loaded) return; this.world.removeLoadedChunk(this); - this.deactivateAllBlockEntities(); this.loaded = false; } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/CachedStorage.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/CachedStorage.java index 23fd7cd94..0bb78e303 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/CachedStorage.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/CachedStorage.java @@ -26,6 +26,11 @@ public class CachedStorage implements WorldDataStora .build(); } + @Override + public CEChunk readNewChunkAt(CEWorld world, ChunkPos pos) throws IOException { + return this.storage.readNewChunkAt(world, pos); + } + @Override public @NotNull CEChunk readChunkAt(@NotNull CEWorld world, @NotNull ChunkPos pos) throws IOException { CEChunk chunk = this.chunkCache.getIfPresent(pos); @@ -42,6 +47,12 @@ public class CachedStorage implements WorldDataStora this.storage.writeChunkAt(pos, chunk); } + @Override + public void clearChunkAt(@NotNull ChunkPos pos) throws IOException { + this.storage.clearChunkAt(pos); + this.chunkCache.invalidate(pos); + } + @Override public void close() throws IOException { this.storage.close(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DefaultRegionFileStorage.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DefaultRegionFileStorage.java index bfeef7a58..9010eab47 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DefaultRegionFileStorage.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DefaultRegionFileStorage.java @@ -120,6 +120,19 @@ public class DefaultRegionFileStorage implements WorldDataStorage { } } + @Override + public CEChunk readNewChunkAt(CEWorld world, ChunkPos pos) throws IOException { + RegionFile regionFile = this.getRegionFile(pos, false, true); + try { + if (regionFile.doesChunkExist(pos)) { + regionFile.clear(pos); + } + return new CEChunk(world, pos); + } finally { + regionFile.fileLock.unlock(); + } + } + @Override public @NotNull CEChunk readChunkAt(@NotNull CEWorld world, @NotNull ChunkPos pos) throws IOException { RegionFile regionFile = this.getRegionFile(pos, false, true); @@ -152,6 +165,11 @@ public class DefaultRegionFileStorage implements WorldDataStorage { writeChunkTagAt(pos, nbt); } + @Override + public void clearChunkAt(@NotNull ChunkPos pos) throws IOException { + this.writeChunkTagAt(pos, null); + } + public void writeChunkTagAt(@NotNull ChunkPos pos, @Nullable CompoundTag nbt) throws IOException { RegionFile regionFile = this.getRegionFile(pos, nbt == null, true); try { diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/WorldDataStorage.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/WorldDataStorage.java index bd44492a9..47dff58fe 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/WorldDataStorage.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/WorldDataStorage.java @@ -9,11 +9,18 @@ import java.io.IOException; public interface WorldDataStorage { + default CEChunk readNewChunkAt(CEWorld world, ChunkPos pos) throws IOException { + this.clearChunkAt(pos); + return this.readChunkAt(world, pos); + } + @NotNull CEChunk readChunkAt(@NotNull CEWorld world, @NotNull ChunkPos pos) throws IOException; void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk) throws IOException; + void clearChunkAt(@NotNull ChunkPos pos) throws IOException; + void flush() throws IOException; void close() throws IOException; diff --git a/gradle.properties b/gradle.properties index 62d61a0aa..ace5a3031 100644 --- a/gradle.properties +++ b/gradle.properties @@ -49,7 +49,7 @@ byte_buddy_version=1.17.8 ahocorasick_version=0.6.3 snake_yaml_version=2.5 anti_grief_version=1.0.4 -nms_helper_version=1.0.124 +nms_helper_version=1.0.125 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.34.5 From 94a19c61a2235bdf95a9404aa6adc43135210266 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Thu, 6 Nov 2025 00:07:54 +0800 Subject: [PATCH 13/37] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E5=B0=8F=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../craftengine/core/world/chunk/CEChunk.java | 36 +++++++++---------- gradle.properties | 2 +- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java index 960f54a8c..a0babe284 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java @@ -165,29 +165,27 @@ public class CEChunk { } else { outer: for (int i = 0; i < elements.length; i++) { BlockEntityElementConfig config = renderers[i]; - { - for (int j = 0; j < previousElements.length; j++) { - BlockEntityElement previousElement = previousElements[j]; - if (previousElement != null && config.elementClass().isInstance(previousElement)) { - BlockEntityElement newElement = ((BlockEntityElementConfig) config).create(wrappedWorld, pos, previousElement); - if (newElement != null) { - previousElements[i] = null; - elements[i] = newElement; - if (hasTrackedBy) { - for (Player player : trackedBy) { - newElement.transform(player); - } + for (int j = 0; j < previousElements.length; j++) { + BlockEntityElement previousElement = previousElements[j]; + if (previousElement != null && config.elementClass().isInstance(previousElement)) { + BlockEntityElement newElement = ((BlockEntityElementConfig) config).create(wrappedWorld, pos, previousElement); + if (newElement != null) { + previousElements[j] = null; + elements[i] = newElement; + if (hasTrackedBy) { + for (Player player : trackedBy) { + newElement.transform(player); } - continue outer; } + continue outer; } } - BlockEntityElement newElement = config.create(wrappedWorld, pos); - elements[i] = newElement; - if (hasTrackedBy) { - for (Player player : trackedBy) { - newElement.show(player); - } + } + BlockEntityElement newElement = config.create(wrappedWorld, pos); + elements[i] = newElement; + if (hasTrackedBy) { + for (Player player : trackedBy) { + newElement.show(player); } } } diff --git a/gradle.properties b/gradle.properties index ace5a3031..60085ac4b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.65.3 +project_version=0.0.65.4 config_version=53 lang_version=37 project_group=net.momirealms From 4240d01c1fd1ae73debb8e57425438f9901863a8 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Thu, 6 Nov 2025 00:30:51 +0800 Subject: [PATCH 14/37] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=A1=AC=E7=BC=96?= =?UTF-8?q?=E7=A0=81=E6=97=8B=E8=BD=AC=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/block/properties/Property.java | 19 +++++- .../craftengine/core/util/SegmentedAngle.java | 58 +++++++++++++++++++ 2 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 core/src/main/java/net/momirealms/craftengine/core/util/SegmentedAngle.java diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/properties/Property.java b/core/src/main/java/net/momirealms/craftengine/core/block/properties/Property.java index f89787fa1..e0bac9608 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/properties/Property.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/properties/Property.java @@ -4,6 +4,8 @@ import net.momirealms.craftengine.core.block.ImmutableBlockState; import net.momirealms.craftengine.core.item.context.BlockPlaceContext; import net.momirealms.craftengine.core.util.Direction; import net.momirealms.craftengine.core.util.HorizontalDirection; +import net.momirealms.craftengine.core.util.MiscUtils; +import net.momirealms.craftengine.core.util.SegmentedAngle; import net.momirealms.sparrow.nbt.Tag; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -33,7 +35,7 @@ public abstract class Property> { Property directionProperty = (Property) property; return (context, state) -> state.with(directionProperty, context.getNearestLookingDirection().opposite()); } else { - throw new IllegalArgumentException("Unsupported property type used in hard-coded `facing` property: " + property.valueClass()); + return (context, state) -> state; } })); HARD_CODED_PLACEMENTS.put("facing_clockwise", (property -> { @@ -41,13 +43,26 @@ public abstract class Property> { Property directionProperty = (Property) property; return (context, state) -> state.with(directionProperty, context.getHorizontalDirection().clockWise().toHorizontalDirection()); } else { - throw new IllegalArgumentException("Unsupported property type used in hard-coded `facing_clockwise` property: " + property.valueClass()); + return (context, state) -> state; } })); HARD_CODED_PLACEMENTS.put("waterlogged", (property -> { Property waterloggedProperty = (Property) property; return (context, state) -> state.with(waterloggedProperty, context.isWaterSource()); })); + HARD_CODED_PLACEMENTS.put("rotation", property -> { + if (property.valueClass() == Integer.class) { + IntegerProperty rotationProperty = (IntegerProperty) property; + if (rotationProperty.min == 0 && rotationProperty.max > 0) { + return (context, state) -> { + float rotation = context.getRotation(); + SegmentedAngle segmentedAngle = new SegmentedAngle(rotationProperty.max + 1); + return state.with(rotationProperty, segmentedAngle.fromDegrees(rotation + 180)); + }; + } + } + return (context, state) -> state; + }); } private final Class clazz; diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/SegmentedAngle.java b/core/src/main/java/net/momirealms/craftengine/core/util/SegmentedAngle.java new file mode 100644 index 000000000..9d1aea132 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/util/SegmentedAngle.java @@ -0,0 +1,58 @@ +package net.momirealms.craftengine.core.util; + +public class SegmentedAngle { + private final int segments; + private final float degreeToAngle; + private final float angleToDegree; + + public SegmentedAngle(int segments) { + if (segments < 2) { + throw new IllegalArgumentException("Segments cannot be less than 2"); + } else if (segments > 360) { + throw new IllegalArgumentException("Segments cannot be greater than 360"); + } else { + this.segments = segments; + this.degreeToAngle = (float) segments / 360.0F; + this.angleToDegree = 360.0F / (float) segments; + } + } + + public boolean isSameAxis(int alpha, int beta) { + int halfSegments = this.segments / 2; + return (alpha % halfSegments) == (beta % halfSegments); + } + + public int fromDirection(Direction direction) { + if (direction.axis().isVertical()) { + return 0; + } else { + int i = direction.data2d(); + return i * (this.segments / 4); + } + } + + public int fromDegreesWithTurns(float degrees) { + return Math.round(degrees * this.degreeToAngle); + } + + public int fromDegrees(float degrees) { + return this.normalize(this.fromDegreesWithTurns(degrees)); + } + + public float toDegreesWithTurns(int rotation) { + return (float) rotation * this.angleToDegree; + } + + public float toDegrees(int rotation) { + float f = this.toDegreesWithTurns(this.normalize(rotation)); + return f >= 180.0F ? f - 360.0F : f; + } + + public int normalize(int rotationBits) { + return ((rotationBits % this.segments) + this.segments) % this.segments; + } + + public int getSegments() { + return this.segments; + } +} \ No newline at end of file From 4abb0124f729a4b21dd366c5d040e85d6c2f78be Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Thu, 6 Nov 2025 00:40:47 +0800 Subject: [PATCH 15/37] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dentity-renderer?= =?UTF-8?q?=E6=97=8B=E8=BD=AC=E9=80=A0=E6=88=90=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ItemDisplayBlockEntityElementConfig.java | 4 + .../TextDisplayBlockEntityElementConfig.java | 4 + .../default/configuration/templates.yml | 192 +++++++++--------- 3 files changed, 104 insertions(+), 96 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElementConfig.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElementConfig.java index 3414f1988..ac9895063 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElementConfig.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElementConfig.java @@ -80,6 +80,10 @@ public class ItemDisplayBlockEntityElementConfig implements BlockEntityElementCo @Override public ItemDisplayBlockEntityElement create(World world, BlockPos pos, ItemDisplayBlockEntityElement previous) { + Quaternionf previousRotation = previous.config.rotation; + if (previousRotation.x != 0 || previousRotation.y != 0 || previousRotation.z != 0 || previousRotation.w != 1) { + return null; + } return new ItemDisplayBlockEntityElement(this, pos, previous.entityId, previous.config.yRot != this.yRot || !previous.config.position.equals(this.position)); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElementConfig.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElementConfig.java index 9156d7d4b..569b7583f 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElementConfig.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElementConfig.java @@ -68,6 +68,10 @@ public class TextDisplayBlockEntityElementConfig implements BlockEntityElementCo @Override public TextDisplayBlockEntityElement create(World world, BlockPos pos, TextDisplayBlockEntityElement previous) { + Quaternionf previousRotation = previous.config.rotation; + if (previousRotation.x != 0 || previousRotation.y != 0 || previousRotation.z != 0 || previousRotation.w != 1) { + return null; + } return new TextDisplayBlockEntityElement(this, pos, previous.entityId, previous.config.yRot != this.yRot || !previous.config.position.equals(this.position)); } diff --git a/common-files/src/main/resources/resources/default/configuration/templates.yml b/common-files/src/main/resources/resources/default/configuration/templates.yml index 82fc59d30..d22288ef0 100644 --- a/common-files/src/main/resources/resources/default/configuration/templates.yml +++ b/common-files/src/main/resources/resources/default/configuration/templates.yml @@ -2682,354 +2682,354 @@ templates#block_states: state: ${base_block}[east=false,north=false,south=false,waterlogged=false,west=false] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 east=true,north=false,south=false,waterlogged=false,west=false: state: ${base_block}[east=true,north=false,south=false,waterlogged=false,west=false] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 270 + yaw: 270 east=false,north=true,south=false,waterlogged=false,west=false: state: ${base_block}[east=false,north=true,south=false,waterlogged=false,west=false] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 180 + yaw: 180 east=false,north=false,south=true,waterlogged=false,west=false: state: ${base_block}[east=false,north=false,south=true,waterlogged=false,west=false] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 0 + yaw: 0 east=false,north=false,south=false,waterlogged=false,west=true: state: ${base_block}[east=false,north=false,south=false,waterlogged=false,west=true] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 90 + yaw: 90 east=true,north=true,south=false,waterlogged=false,west=false: state: ${base_block}[east=true,north=true,south=false,waterlogged=false,west=false] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 180 + yaw: 180 - item: ${fence_side_item} - rotation: 270 + yaw: 270 east=true,north=false,south=true,waterlogged=false,west=false: state: ${base_block}[east=true,north=false,south=true,waterlogged=false,west=false] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 0 + yaw: 0 - item: ${fence_side_item} - rotation: 270 + yaw: 270 east=true,north=false,south=false,waterlogged=false,west=true: state: ${base_block}[east=true,north=false,south=false,waterlogged=false,west=true] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 90 + yaw: 90 - item: ${fence_side_item} - rotation: 270 + yaw: 270 east=false,north=true,south=true,waterlogged=false,west=false: state: ${base_block}[east=false,north=true,south=true,waterlogged=false,west=false] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 0 + yaw: 0 - item: ${fence_side_item} - rotation: 180 + yaw: 180 east=false,north=true,south=false,waterlogged=false,west=true: state: ${base_block}[east=false,north=true,south=false,waterlogged=false,west=true] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 90 + yaw: 90 - item: ${fence_side_item} - rotation: 180 + yaw: 180 east=false,north=false,south=true,waterlogged=false,west=true: state: ${base_block}[east=false,north=false,south=true,waterlogged=false,west=true] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 0 + yaw: 0 - item: ${fence_side_item} - rotation: 90 + yaw: 90 east=true,north=true,south=true,waterlogged=false,west=false: state: ${base_block}[east=true,north=true,south=true,waterlogged=false,west=false] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 0 + yaw: 0 - item: ${fence_side_item} - rotation: 180 + yaw: 180 - item: ${fence_side_item} - rotation: 270 + yaw: 270 east=true,north=true,south=false,waterlogged=false,west=true: state: ${base_block}[east=true,north=true,south=false,waterlogged=false,west=true] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 90 + yaw: 90 - item: ${fence_side_item} - rotation: 180 + yaw: 180 - item: ${fence_side_item} - rotation: 270 + yaw: 270 east=true,north=false,south=true,waterlogged=false,west=true: state: ${base_block}[east=true,north=false,south=true,waterlogged=false,west=true] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 0 + yaw: 0 - item: ${fence_side_item} - rotation: 90 + yaw: 90 - item: ${fence_side_item} - rotation: 270 + yaw: 270 east=false,north=true,south=true,waterlogged=false,west=true: state: ${base_block}[east=false,north=true,south=true,waterlogged=false,west=true] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 0 + yaw: 0 - item: ${fence_side_item} - rotation: 90 + yaw: 90 - item: ${fence_side_item} - rotation: 180 + yaw: 180 east=true,north=true,south=true,waterlogged=false,west=true: state: ${base_block}[east=true,north=true,south=true,waterlogged=false,west=true] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 0 + yaw: 0 - item: ${fence_side_item} - rotation: 90 + yaw: 90 - item: ${fence_side_item} - rotation: 180 + yaw: 180 - item: ${fence_side_item} - rotation: 270 + yaw: 270 east=false,north=false,south=false,waterlogged=true,west=false: state: ${base_block}[east=false,north=false,south=false,waterlogged=true,west=false] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 east=true,north=false,south=false,waterlogged=true,west=false: state: ${base_block}[east=true,north=false,south=false,waterlogged=true,west=false] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 270 + yaw: 270 east=false,north=true,south=false,waterlogged=true,west=false: state: ${base_block}[east=false,north=true,south=false,waterlogged=true,west=false] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 180 + yaw: 180 east=false,north=false,south=true,waterlogged=true,west=false: state: ${base_block}[east=false,north=false,south=true,waterlogged=true,west=false] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 0 + yaw: 0 east=false,north=false,south=false,waterlogged=true,west=true: state: ${base_block}[east=false,north=false,south=false,waterlogged=true,west=true] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 90 + yaw: 90 east=true,north=true,south=false,waterlogged=true,west=false: state: ${base_block}[east=true,north=true,south=false,waterlogged=true,west=false] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 180 + yaw: 180 - item: ${fence_side_item} - rotation: 270 + yaw: 270 east=true,north=false,south=true,waterlogged=true,west=false: state: ${base_block}[east=true,north=false,south=true,waterlogged=true,west=false] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 0 + yaw: 0 - item: ${fence_side_item} - rotation: 270 + yaw: 270 east=true,north=false,south=false,waterlogged=true,west=true: state: ${base_block}[east=true,north=false,south=false,waterlogged=true,west=true] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 90 + yaw: 90 - item: ${fence_side_item} - rotation: 270 + yaw: 270 east=false,north=true,south=true,waterlogged=true,west=false: state: ${base_block}[east=false,north=true,south=true,waterlogged=true,west=false] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 0 + yaw: 0 - item: ${fence_side_item} - rotation: 180 + yaw: 180 east=false,north=true,south=false,waterlogged=true,west=true: state: ${base_block}[east=false,north=true,south=false,waterlogged=true,west=true] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 90 + yaw: 90 - item: ${fence_side_item} - rotation: 180 + yaw: 180 east=false,north=false,south=true,waterlogged=true,west=true: state: ${base_block}[east=false,north=false,south=true,waterlogged=true,west=true] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 0 + yaw: 0 - item: ${fence_side_item} - rotation: 90 + yaw: 90 east=true,north=true,south=true,waterlogged=true,west=false: state: ${base_block}[east=true,north=true,south=true,waterlogged=true,west=false] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 0 + yaw: 0 - item: ${fence_side_item} - rotation: 180 + yaw: 180 - item: ${fence_side_item} - rotation: 270 + yaw: 270 east=true,north=true,south=false,waterlogged=true,west=true: state: ${base_block}[east=true,north=true,south=false,waterlogged=true,west=true] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 90 + yaw: 90 - item: ${fence_side_item} - rotation: 180 + yaw: 180 - item: ${fence_side_item} - rotation: 270 + yaw: 270 east=true,north=false,south=true,waterlogged=true,west=true: state: ${base_block}[east=true,north=false,south=true,waterlogged=true,west=true] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 0 + yaw: 0 - item: ${fence_side_item} - rotation: 90 + yaw: 90 - item: ${fence_side_item} - rotation: 270 + yaw: 270 east=false,north=true,south=true,waterlogged=true,west=true: state: ${base_block}[east=false,north=true,south=true,waterlogged=true,west=true] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 0 + yaw: 0 - item: ${fence_side_item} - rotation: 90 + yaw: 90 - item: ${fence_side_item} - rotation: 180 + yaw: 180 east=true,north=true,south=true,waterlogged=true,west=true: state: ${base_block}[east=true,north=true,south=true,waterlogged=true,west=true] entity-renderer: - item: ${fence_post_item} - rotation: 180 + yaw: 180 scale: 1.0003 translation: 0,0.0001,0 - item: ${fence_side_item} - rotation: 0 + yaw: 0 - item: ${fence_side_item} - rotation: 90 + yaw: 90 - item: ${fence_side_item} - rotation: 180 + yaw: 180 - item: ${fence_side_item} - rotation: 270 + yaw: 270 variants: waterlogged=true: settings: From d78b50c9160dbe488a08c5efe02e76dd44741756 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Thu, 6 Nov 2025 13:46:15 +0800 Subject: [PATCH 16/37] =?UTF-8?q?=E5=AE=8C=E5=96=84entity-renderer?= =?UTF-8?q?=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BetterModelBlockEntityElement.java | 7 +++- .../BetterModelBlockEntityElementConfig.java | 40 ++++++++++++++++--- .../ItemDisplayBlockEntityElementConfig.java | 2 +- .../TextDisplayBlockEntityElementConfig.java | 2 +- .../core/block/properties/Property.java | 1 - 5 files changed, 42 insertions(+), 10 deletions(-) diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelBlockEntityElement.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelBlockEntityElement.java index 1c9a0e5d3..e67ffdda1 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelBlockEntityElement.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelBlockEntityElement.java @@ -3,6 +3,7 @@ package net.momirealms.craftengine.bukkit.compatibility.model.bettermodel; import kr.toxicity.model.api.BetterModel; import kr.toxicity.model.api.data.renderer.ModelRenderer; import kr.toxicity.model.api.tracker.DummyTracker; +import kr.toxicity.model.api.tracker.TrackerModifier; import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityElement; import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.world.BlockPos; @@ -27,7 +28,11 @@ public class BetterModelBlockEntityElement implements BlockEntityElement { if (modelRenderer == null) { return null; } else { - return modelRenderer.create(this.location); + return modelRenderer.create(this.location, TrackerModifier.builder() + .viewRange(this.config.viewRange()) + .sightTrace(this.config.sightTrace()) + .shadow(this.config.shadow()) + .build()); } } diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelBlockEntityElementConfig.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelBlockEntityElementConfig.java index 7127e4966..b6fa362ad 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelBlockEntityElementConfig.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelBlockEntityElementConfig.java @@ -6,6 +6,7 @@ import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityEl import net.momirealms.craftengine.core.util.ResourceConfigUtils; import net.momirealms.craftengine.core.world.BlockPos; import net.momirealms.craftengine.core.world.World; +import org.bukkit.Bukkit; import org.joml.Vector3f; import java.util.Map; @@ -15,28 +16,52 @@ public class BetterModelBlockEntityElementConfig implements BlockEntityElementCo private final float yaw; private final float pitch; private final String model; + private final float viewRange; + private final boolean sightTrace; + private final boolean shadow; - public BetterModelBlockEntityElementConfig(String model, Vector3f position, float yaw, float pitch) { + public BetterModelBlockEntityElementConfig(String model, + Vector3f position, + float yaw, + float pitch, + float viewRange, + boolean sightTrace, + boolean shadow) { this.pitch = pitch; this.position = position; this.yaw = yaw; this.model = model; + this.viewRange = viewRange; + this.sightTrace = sightTrace; + this.shadow = shadow; } public String model() { - return model; + return this.model; } public float pitch() { - return pitch; + return this.pitch; } public Vector3f position() { - return position; + return this.position; } public float yaw() { - return yaw; + return this.yaw; + } + + public float viewRange() { + return this.viewRange; + } + + public boolean sightTrace() { + return this.sightTrace; + } + + public boolean shadow() { + return this.shadow; } @Override @@ -59,7 +84,10 @@ public class BetterModelBlockEntityElementConfig implements BlockEntityElementCo model, ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("position", 0.5f), "position"), ResourceConfigUtils.getAsFloat(arguments.getOrDefault("yaw", 0f), "yaw"), - ResourceConfigUtils.getAsFloat(arguments.getOrDefault("pitch", 0f), "pitch") + ResourceConfigUtils.getAsFloat(arguments.getOrDefault("pitch", 0f), "pitch"), + ResourceConfigUtils.getAsFloat(arguments.getOrDefault("view-range", (float) Bukkit.getViewDistance() / 4.0F), "view-range"), + ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("sight-trace", true), "sight-trace"), + ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("shadow", true), "shadow") ); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElementConfig.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElementConfig.java index ac9895063..d3a2d1dd8 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElementConfig.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElementConfig.java @@ -84,7 +84,7 @@ public class ItemDisplayBlockEntityElementConfig implements BlockEntityElementCo if (previousRotation.x != 0 || previousRotation.y != 0 || previousRotation.z != 0 || previousRotation.w != 1) { return null; } - return new ItemDisplayBlockEntityElement(this, pos, previous.entityId, previous.config.yRot != this.yRot || !previous.config.position.equals(this.position)); + return new ItemDisplayBlockEntityElement(this, pos, previous.entityId, previous.config.yRot != this.yRot || previous.config.xRot != this.xRot || !previous.config.position.equals(this.position)); } @Override diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElementConfig.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElementConfig.java index 569b7583f..14f4a3210 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElementConfig.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElementConfig.java @@ -72,7 +72,7 @@ public class TextDisplayBlockEntityElementConfig implements BlockEntityElementCo if (previousRotation.x != 0 || previousRotation.y != 0 || previousRotation.z != 0 || previousRotation.w != 1) { return null; } - return new TextDisplayBlockEntityElement(this, pos, previous.entityId, previous.config.yRot != this.yRot || !previous.config.position.equals(this.position)); + return new TextDisplayBlockEntityElement(this, pos, previous.entityId, previous.config.yRot != this.yRot || previous.config.xRot != this.xRot || !previous.config.position.equals(this.position)); } @Override diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/properties/Property.java b/core/src/main/java/net/momirealms/craftengine/core/block/properties/Property.java index e0bac9608..b0eb72d4b 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/properties/Property.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/properties/Property.java @@ -4,7 +4,6 @@ import net.momirealms.craftengine.core.block.ImmutableBlockState; import net.momirealms.craftengine.core.item.context.BlockPlaceContext; import net.momirealms.craftengine.core.util.Direction; import net.momirealms.craftengine.core.util.HorizontalDirection; -import net.momirealms.craftengine.core.util.MiscUtils; import net.momirealms.craftengine.core.util.SegmentedAngle; import net.momirealms.sparrow.nbt.Tag; import org.jetbrains.annotations.NotNull; From c94bcbbe28d694ddc9e903db029f8e73a574ee90 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Thu, 6 Nov 2025 14:07:05 +0800 Subject: [PATCH 17/37] =?UTF-8?q?item=20data=E9=98=B2=E5=91=86=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bukkit/compatibility/build.gradle.kts | 5 +++-- .../BetterModelBlockEntityElement.java | 4 +--- .../BetterModelBlockEntityElementConfig.java | 21 ++----------------- .../model/bettermodel/BetterModelUtils.java | 2 +- .../core/item/modifier/ItemDataModifiers.java | 4 ++++ 5 files changed, 11 insertions(+), 25 deletions(-) diff --git a/bukkit/compatibility/build.gradle.kts b/bukkit/compatibility/build.gradle.kts index 933d60862..949b79fe4 100644 --- a/bukkit/compatibility/build.gradle.kts +++ b/bukkit/compatibility/build.gradle.kts @@ -37,8 +37,9 @@ dependencies { compileOnly("com.infernalsuite.asp:api:4.0.0-SNAPSHOT") // ModelEngine compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.8") - // BetterModels - compileOnly("io.github.toxicity188:BetterModel:1.7.0") + // BetterModel + compileOnly("io.github.toxicity188:bettermodel:1.14.0") + compileOnly("com.mojang:authlib:${rootProject.properties["authlib_version"]}") // MMOItems compileOnly("net.Indyuce:MMOItems-API:6.10-SNAPSHOT") compileOnly("io.lumine:MythicLib-dist:1.6.2-SNAPSHOT") diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelBlockEntityElement.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelBlockEntityElement.java index e67ffdda1..c30ca33db 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelBlockEntityElement.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelBlockEntityElement.java @@ -24,14 +24,12 @@ public class BetterModelBlockEntityElement implements BlockEntityElement { } private DummyTracker createDummyTracker() { - ModelRenderer modelRenderer = BetterModel.plugin().modelManager().renderer(this.config.model()); + ModelRenderer modelRenderer = BetterModel.plugin().modelManager().model(this.config.model()); if (modelRenderer == null) { return null; } else { return modelRenderer.create(this.location, TrackerModifier.builder() - .viewRange(this.config.viewRange()) .sightTrace(this.config.sightTrace()) - .shadow(this.config.shadow()) .build()); } } diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelBlockEntityElementConfig.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelBlockEntityElementConfig.java index b6fa362ad..a6c936826 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelBlockEntityElementConfig.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelBlockEntityElementConfig.java @@ -6,7 +6,6 @@ import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityEl import net.momirealms.craftengine.core.util.ResourceConfigUtils; import net.momirealms.craftengine.core.world.BlockPos; import net.momirealms.craftengine.core.world.World; -import org.bukkit.Bukkit; import org.joml.Vector3f; import java.util.Map; @@ -16,24 +15,18 @@ public class BetterModelBlockEntityElementConfig implements BlockEntityElementCo private final float yaw; private final float pitch; private final String model; - private final float viewRange; private final boolean sightTrace; - private final boolean shadow; public BetterModelBlockEntityElementConfig(String model, Vector3f position, float yaw, float pitch, - float viewRange, - boolean sightTrace, - boolean shadow) { + boolean sightTrace) { this.pitch = pitch; this.position = position; this.yaw = yaw; this.model = model; - this.viewRange = viewRange; this.sightTrace = sightTrace; - this.shadow = shadow; } public String model() { @@ -52,18 +45,10 @@ public class BetterModelBlockEntityElementConfig implements BlockEntityElementCo return this.yaw; } - public float viewRange() { - return this.viewRange; - } - public boolean sightTrace() { return this.sightTrace; } - public boolean shadow() { - return this.shadow; - } - @Override public BetterModelBlockEntityElement create(World world, BlockPos pos) { return new BetterModelBlockEntityElement(world, pos, this); @@ -85,9 +70,7 @@ public class BetterModelBlockEntityElementConfig implements BlockEntityElementCo ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("position", 0.5f), "position"), ResourceConfigUtils.getAsFloat(arguments.getOrDefault("yaw", 0f), "yaw"), ResourceConfigUtils.getAsFloat(arguments.getOrDefault("pitch", 0f), "pitch"), - ResourceConfigUtils.getAsFloat(arguments.getOrDefault("view-range", (float) Bukkit.getViewDistance() / 4.0F), "view-range"), - ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("sight-trace", true), "sight-trace"), - ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("shadow", true), "shadow") + ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("sight-trace", true), "sight-trace") ); } } diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelUtils.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelUtils.java index 507901517..dbe86e340 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelUtils.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/model/bettermodel/BetterModelUtils.java @@ -9,7 +9,7 @@ import org.bukkit.entity.Entity; public class BetterModelUtils { public static void bindModel(Entity base, String id) { - ModelRenderer renderer = BetterModel.plugin().modelManager().renderer(id); + ModelRenderer renderer = BetterModel.plugin().modelManager().model(id); if (renderer == null) { throw new NullPointerException("Could not find BetterModel blueprint " + id); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemDataModifiers.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemDataModifiers.java index 055746d59..e35e432fb 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemDataModifiers.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemDataModifiers.java @@ -28,6 +28,7 @@ public final class ItemDataModifiers { public static final Key CUSTOM_NAME = Key.of("craftengine:custom-name"); public static final Key CUSTOM_MODEL_DATA = Key.of("craftengine:custom-model-data"); public static final Key COMPONENTS = Key.of("craftengine:components"); + public static final Key COMPONENT = Key.of("craftengine:component"); public static final Key ATTRIBUTE_MODIFIERS = Key.of("craftengine:attribute-modifiers"); public static final Key ATTRIBUTES = Key.of("craftengine:attributes"); public static final Key ARGUMENTS = Key.of("craftengine:arguments"); @@ -37,6 +38,7 @@ public final class ItemDataModifiers { public static final Key OVERWRITABLE_ITEM_NAME = Key.of("craftengine:overwritable-item-name"); public static final Key JUKEBOX_PLAYABLE = Key.of("craftengine:jukebox-playable"); public static final Key REMOVE_COMPONENTS = Key.of("craftengine:remove-components"); + public static final Key REMOVE_COMPONENT = Key.of("craftengine:remove-component"); public static final Key TAGS = Key.of("craftengine:tags"); public static final Key NBT = Key.of("craftengine:nbt"); public static final Key TOOLTIP_STYLE = Key.of("craftengine:tooltip-style"); @@ -84,7 +86,9 @@ public final class ItemDataModifiers { register(ITEM_NAME, ItemNameModifier.FACTORY); register(DISPLAY_NAME, ItemNameModifier.FACTORY); register(COMPONENTS, ComponentsModifier.FACTORY); + register(COMPONENT, ComponentsModifier.FACTORY); register(REMOVE_COMPONENTS, RemoveComponentModifier.FACTORY); + register(REMOVE_COMPONENT, RemoveComponentModifier.FACTORY); register(FOOD, FoodModifier.FACTORY); register(MAX_DAMAGE, MaxDamageModifier.FACTORY); } else { From 6c7b13a688abfc48f1689a1c986620e7b09c45d3 Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Thu, 6 Nov 2025 17:15:09 +0800 Subject: [PATCH 18/37] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E4=B8=8E=E5=AE=A2?= =?UTF-8?q?=E6=88=B7=E7=AB=AF=E6=A8=A1=E7=BB=84=E7=9A=84=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../protocol/ClientCustomBlockPacket.java | 2 +- .../craftengine/core/util/VersionHelper.java | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/payload/protocol/ClientCustomBlockPacket.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/payload/protocol/ClientCustomBlockPacket.java index eee81789d..e63cfd630 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/payload/protocol/ClientCustomBlockPacket.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/payload/protocol/ClientCustomBlockPacket.java @@ -56,7 +56,7 @@ public record ClientCustomBlockPacket(int vanillaSize, int currentSize) implemen return; } int serverBlockRegistrySize = RegistryUtils.currentBlockRegistrySize(); - if (this.currentSize != serverBlockRegistrySize) { + if (this.currentSize < serverBlockRegistrySize) { user.kick(Component.translatable( "disconnect.craftengine.current_block_registry_mismatch", TranslationArgument.numeric(this.currentSize), 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 b0b7a6031..633dcba99 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 @@ -5,6 +5,7 @@ import com.google.gson.JsonObject; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; +import java.util.Objects; public class VersionHelper { public static final boolean PREMIUM = true; @@ -35,20 +36,30 @@ public class VersionHelper { private static final boolean v1_21_8; private static final boolean v1_21_9; private static final boolean v1_21_10; + private static final Class UNOBFUSCATED_CLAZZ = Objects.requireNonNull(ReflectionUtils.getClazz( + "net.minecraft.obfuscate.DontObfuscate", // 因为无混淆版本没有这个类所以说多写几个防止找不到了 + "net.minecraft.data.Main", + "net.minecraft.server.Main", + "net.minecraft.gametest.Main", + "net.minecraft.client.main.Main", + "net.minecraft.client.data.Main" + )); static { - try (InputStream inputStream = Class.forName("net.minecraft.obfuscate.DontObfuscate").getResourceAsStream("/version.json")) { + try (InputStream inputStream = UNOBFUSCATED_CLAZZ.getResourceAsStream("/version.json")) { if (inputStream == null) { throw new IOException("Failed to load version.json"); } JsonObject json = GsonHelper.parseJsonToJsonObject(new String(inputStream.readAllBytes(), StandardCharsets.UTF_8)); - String versionString = json.getAsJsonPrimitive("id").getAsString().split("-", 2)[0]; + String versionString = json.getAsJsonPrimitive("id").getAsString() + .split("-", 2)[0] // 1.21.10-rc1 -> 1.21.10 + .split("_", 2)[0]; // 1.21.11_unobfuscated -> 1.21.11 MINECRAFT_VERSION = new MinecraftVersion(versionString); String[] split = versionString.split("\\."); int major = Integer.parseInt(split[1]); - int minor = split.length == 3 ? Integer.parseInt(split[2].split("-", 2)[0]) : 0; + int minor = split.length == 3 ? Integer.parseInt(split[2]) : 0; // 12001 = 1.20.1 // 12104 = 1.21.4 From bd264f1a6bdc6d5a3a9c4042ab06a2fcfc94a947 Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Thu, 6 Nov 2025 17:59:48 +0800 Subject: [PATCH 19/37] =?UTF-8?q?=E4=BF=AE=E5=A4=8D1.20.5=E6=8A=A5?= =?UTF-8?q?=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/reflection/minecraft/CoreReflections.java | 7 +++---- gradle.properties | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) 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 3931bdbd3..228669d01 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 @@ -3133,10 +3133,9 @@ public final class CoreReflections { ); public static final Class clazz$ChunkMap = requireNonNull( - BukkitReflectionUtils.findReobfOrMojmapClass( - "server.level.PlayerChunkMap", - "server.level.PlayerChunkMap" // paper remap的问题,所以使用旧mapping -// "server.level.ChunkMap" + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleMCClass("server.level.PlayerChunkMap"), // 这里paper会自动获取到NM.server.level.ChunkMap + BukkitReflectionUtils.assembleMCClass("server.level.ChunkMap") // 如果插件是mojmap就会走这个 ) ); diff --git a/gradle.properties b/gradle.properties index 60085ac4b..aaa78ecb1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -49,7 +49,7 @@ byte_buddy_version=1.17.8 ahocorasick_version=0.6.3 snake_yaml_version=2.5 anti_grief_version=1.0.4 -nms_helper_version=1.0.125 +nms_helper_version=1.0.126 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.34.5 From b291e06036ccffa9400654fd0e908ec151a357f3 Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Thu, 6 Nov 2025 20:11:12 +0800 Subject: [PATCH 20/37] =?UTF-8?q?paper=E6=9F=A0=E6=AA=AC=E9=85=B8=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/reflection/minecraft/CoreReflections.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 228669d01..5547f8c7d 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 @@ -1082,7 +1082,7 @@ public final class CoreReflections { public static final Class clazz$MobEffect = requireNonNull( ReflectionUtils.getClazz( BukkitReflectionUtils.assembleMCClass("world.effect.MobEffectList"), // 这里paper会自动获取到NM.world.effect.MobEffect - BukkitReflectionUtils.assembleMCClass("world.effect.MobEffect") // 如果插件是mojmap就会走这个 + BukkitReflectionUtils.assembleMCClass("world.effect.MobEffect") // paper柠檬酸了 ) ); @@ -1125,7 +1125,7 @@ public final class CoreReflections { public static final Class clazz$Fluid = requireNonNull( ReflectionUtils.getClazz( BukkitReflectionUtils.assembleMCClass("world.level.material.FluidType"), // 这里paper会自动获取到NM.world.level.material.Fluid - BukkitReflectionUtils.assembleMCClass("world.level.material.Fluid") // 如果插件是mojmap就会走这个 + BukkitReflectionUtils.assembleMCClass("world.level.material.Fluid") // paper柠檬酸了 ) ); @@ -3135,7 +3135,7 @@ public final class CoreReflections { public static final Class clazz$ChunkMap = requireNonNull( ReflectionUtils.getClazz( BukkitReflectionUtils.assembleMCClass("server.level.PlayerChunkMap"), // 这里paper会自动获取到NM.server.level.ChunkMap - BukkitReflectionUtils.assembleMCClass("server.level.ChunkMap") // 如果插件是mojmap就会走这个 + BukkitReflectionUtils.assembleMCClass("server.level.ChunkMap") // paper柠檬酸了 ) ); @@ -3238,7 +3238,7 @@ public final class CoreReflections { public static final Class clazz$ResourceManager = requireNonNull( ReflectionUtils.getClazz( BukkitReflectionUtils.assembleMCClass("server.packs.resources.IResourceManager"), // 这里paper会自动获取到NM.server.packs.resources.ResourceManager - BukkitReflectionUtils.assembleMCClass("server.packs.resources.ResourceManager") // 如果插件是mojmap就会走这个 + BukkitReflectionUtils.assembleMCClass("server.packs.resources.ResourceManager") // paper柠檬酸了 ) ); From f6be8b012c750ad8b46ec6519474dddea3235f28 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Thu, 6 Nov 2025 20:40:43 +0800 Subject: [PATCH 21/37] Update gradle.properties --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index aaa78ecb1..6c85cac44 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.65.4 +project_version=0.0.65.5 config_version=53 lang_version=37 project_group=net.momirealms From 58843ecb67421c15ceb4343b20fe0e2e3fd6059a Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Fri, 7 Nov 2025 20:38:59 +0800 Subject: [PATCH 22/37] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtag=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/block/BukkitBlockManager.java | 13 ++---- .../plugin/network/BukkitNetworkManager.java | 13 ++++-- .../minecraft/NetworkReflections.java | 6 +++ .../craftengine/bukkit/util/TagUtils.java | 44 +++++++++++++++++++ 4 files changed, 64 insertions(+), 12 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java index b650e0a57..afde7e0f4 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java @@ -59,7 +59,7 @@ public final class BukkitBlockManager extends AbstractBlockManager { private Map> clientBoundTags = Map.of(); private Map> previousClientBoundTags = Map.of(); // 缓存的原版方块tag包 - private Object cachedUpdateTagsPacket; + private Map> cachedUpdateTags; // 被移除声音的原版方块 private Set missingPlaceSounds = Set.of(); private Set missingBreakSounds = Set.of(); @@ -157,16 +157,11 @@ public final class BukkitBlockManager extends AbstractBlockManager { for (Map.Entry> entry : this.clientBoundTags.entrySet()) { list.add(new TagUtils.TagEntry(entry.getKey(), entry.getValue())); } + this.cachedUpdateTags = Map.of(MRegistries.BLOCK, list); Object packet = TagUtils.createUpdateTagsPacket(Map.of(MRegistries.BLOCK, list)); for (BukkitServerPlayer player : this.plugin.networkManager().onlineUsers()) { player.sendPacket(packet, false); } - // 如果空,那么新来的玩家就没必要收到更新包了 - if (list.isEmpty()) { - this.cachedUpdateTagsPacket = null; - } else { - this.cachedUpdateTagsPacket = packet; - } } @Nullable @@ -364,8 +359,8 @@ public final class BukkitBlockManager extends AbstractBlockManager { } } - public Object cachedUpdateTagsPacket() { - return this.cachedUpdateTagsPacket; + public Map> cachedUpdateTags() { + return this.cachedUpdateTags; } public VisualBlockStatePacket cachedVisualBlockStatePacket() { 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 f7a0ec525..4b6e39545 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 @@ -1857,11 +1857,18 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes public static class UpdateTagsListener implements NMSPacketListener { + @SuppressWarnings("unchecked") @Override public void onPacketSend(NetWorkUser user, NMSPacketEvent event, Object packet) { - Object modifiedPacket = BukkitBlockManager.instance().cachedUpdateTagsPacket(); - if (packet.equals(modifiedPacket) || modifiedPacket == null) return; - event.replacePacket(modifiedPacket); + Map tags; + try { + tags = (Map) NetworkReflections.field$ClientboundUpdateTagsPacket$tags.get(packet); + } catch (Throwable e) { + CraftEngine.instance().logger().warn("Failed to get tags from ClientboundUpdateTagsPacket", e); + return; + } + if (tags.get(MRegistries.BLOCK) == null) return; + event.replacePacket(TagUtils.createUpdateTagsPacket(BukkitBlockManager.instance().cachedUpdateTags(), tags)); } } 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 567234cb1..f5b1e4ee9 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 @@ -1720,4 +1720,10 @@ public final class NetworkReflections { "network.protocol.game.ClientboundBlockEntityDataPacket" ) ); + + public static final Field field$ClientboundUpdateTagsPacket$tags = requireNonNull( + ReflectionUtils.getDeclaredField( + clazz$ClientboundUpdateTagsPacket, Map.class, 0 + ) + ); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/TagUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/TagUtils.java index 530ccc248..51e2887d6 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/TagUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/TagUtils.java @@ -86,4 +86,48 @@ public final class TagUtils { public record TagEntry(int id, List tags) { } + + + public static Object createUpdateTagsPacket(Map> tags, Map existingTags) { + Map modified = new HashMap<>(); + for (Map.Entry payload : existingTags.entrySet()) { + List overrides = tags.get(payload.getKey()); + if (overrides == null || overrides.isEmpty()) { + modified.put(payload.getKey(), payload.getValue()); + continue; + } + FriendlyByteBuf deserializeBuf = new FriendlyByteBuf(Unpooled.buffer()); + FastNMS.INSTANCE.method$TagNetworkSerialization$NetworkPayload$write(payload.getValue(), deserializeBuf); + Map originalTags = deserializeBuf.readMap( + FriendlyByteBuf::readUtf, + FriendlyByteBuf::readIntIdList + ); + Map> reversedTags = new HashMap<>(); + for (Map.Entry tagEntry : originalTags.entrySet()) { + for (int id : tagEntry.getValue()) { + reversedTags.computeIfAbsent(id, k -> new ArrayList<>()).add(tagEntry.getKey()); + } + } + for (TagEntry tagEntry : overrides) { + reversedTags.remove(tagEntry.id); + for (String tag : tagEntry.tags) { + reversedTags.computeIfAbsent(tagEntry.id, k -> new ArrayList<>()).add(tag); + } + } + Map processedTags = new HashMap<>(); + for (Map.Entry> tagEntry : reversedTags.entrySet()) { + for (String tag : tagEntry.getValue()) { + processedTags.computeIfAbsent(tag, k -> new IntArrayList()).addLast(tagEntry.getKey()); + } + } + FriendlyByteBuf serializeBuf = new FriendlyByteBuf(Unpooled.buffer()); + serializeBuf.writeMap(processedTags, + FriendlyByteBuf::writeUtf, + FriendlyByteBuf::writeIntIdList + ); + Object mergedPayload = FastNMS.INSTANCE.method$TagNetworkSerialization$NetworkPayload$read(serializeBuf); + modified.put(payload.getKey(), mergedPayload); + } + return FastNMS.INSTANCE.constructor$ClientboundUpdateTagsPacket(modified); + } } From 1eb9c05a4538b1c571a7b5dae96278c6d16fbc70 Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Fri, 7 Nov 2025 20:46:32 +0800 Subject: [PATCH 23/37] =?UTF-8?q?=E6=94=B9list?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../craftengine/bukkit/block/BukkitBlockManager.java | 6 +++--- .../bukkit/plugin/network/BukkitNetworkManager.java | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java index afde7e0f4..0e5dfb657 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java @@ -59,7 +59,7 @@ public final class BukkitBlockManager extends AbstractBlockManager { private Map> clientBoundTags = Map.of(); private Map> previousClientBoundTags = Map.of(); // 缓存的原版方块tag包 - private Map> cachedUpdateTags; + private List cachedUpdateTags = List.of(); // 被移除声音的原版方块 private Set missingPlaceSounds = Set.of(); private Set missingBreakSounds = Set.of(); @@ -157,7 +157,7 @@ public final class BukkitBlockManager extends AbstractBlockManager { for (Map.Entry> entry : this.clientBoundTags.entrySet()) { list.add(new TagUtils.TagEntry(entry.getKey(), entry.getValue())); } - this.cachedUpdateTags = Map.of(MRegistries.BLOCK, list); + this.cachedUpdateTags = list; Object packet = TagUtils.createUpdateTagsPacket(Map.of(MRegistries.BLOCK, list)); for (BukkitServerPlayer player : this.plugin.networkManager().onlineUsers()) { player.sendPacket(packet, false); @@ -359,7 +359,7 @@ public final class BukkitBlockManager extends AbstractBlockManager { } } - public Map> cachedUpdateTags() { + public List cachedUpdateTags() { return this.cachedUpdateTags; } 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 4b6e39545..2ce8c026c 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 @@ -1860,6 +1860,8 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes @SuppressWarnings("unchecked") @Override public void onPacketSend(NetWorkUser user, NMSPacketEvent event, Object packet) { + List cachedUpdateTags = BukkitBlockManager.instance().cachedUpdateTags(); + if (cachedUpdateTags.isEmpty()) return; Map tags; try { tags = (Map) NetworkReflections.field$ClientboundUpdateTagsPacket$tags.get(packet); @@ -1868,7 +1870,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes return; } if (tags.get(MRegistries.BLOCK) == null) return; - event.replacePacket(TagUtils.createUpdateTagsPacket(BukkitBlockManager.instance().cachedUpdateTags(), tags)); + event.replacePacket(TagUtils.createUpdateTagsPacket(Map.of(MRegistries.BLOCK, cachedUpdateTags), tags)); } } From e00035adf532ae29e1bbceb320993f0b883f756f Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Fri, 7 Nov 2025 21:14:50 +0800 Subject: [PATCH 24/37] =?UTF-8?q?=E4=BC=98=E5=8C=96tags=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/block/BukkitBlockManager.java | 6 +- .../plugin/network/BukkitNetworkManager.java | 24 +++++--- .../craftengine/bukkit/util/TagUtils.java | 55 ++----------------- .../core/block/AbstractBlockManager.java | 4 +- .../craftengine/core/plugin/CraftEngine.java | 2 + .../craftengine/core/util/MarkedHashMap.java | 6 ++ gradle.properties | 2 +- 7 files changed, 34 insertions(+), 65 deletions(-) create mode 100644 core/src/main/java/net/momirealms/craftengine/core/util/MarkedHashMap.java diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java index 0e5dfb657..01d66a69d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java @@ -150,7 +150,7 @@ public final class BukkitBlockManager extends AbstractBlockManager { } @Override - protected void resendTags() { + protected void updateTags() { // if there's no change if (this.clientBoundTags.equals(this.previousClientBoundTags)) return; List list = new ArrayList<>(); @@ -158,10 +158,6 @@ public final class BukkitBlockManager extends AbstractBlockManager { list.add(new TagUtils.TagEntry(entry.getKey(), entry.getValue())); } this.cachedUpdateTags = list; - Object packet = TagUtils.createUpdateTagsPacket(Map.of(MRegistries.BLOCK, list)); - for (BukkitServerPlayer player : this.plugin.networkManager().onlineUsers()) { - player.sendPacket(packet, false); - } } @Nullable 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 2ce8c026c..1ff589e57 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 @@ -241,6 +241,19 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes this.c2sGamePacketListeners[id] = new ByteBufferPacketListenerHolder(name, listener); } + @Override + public void delayedLoad() { + this.resendTags(); + } + + @SuppressWarnings("unchecked") + public void resendTags() { + Object packet = TagUtils.createUpdateTagsPacket(Map.of(MRegistries.BLOCK, BukkitBlockManager.instance().cachedUpdateTags()), FastNMS.INSTANCE.method$TagNetworkSerialization$serializeTagsToNetwork()); + for (BukkitServerPlayer player : onlineUsers()) { + player.sendPacket(packet, false); + } + } + public void addFakePlayer(Player player) { FakeBukkitServerPlayer fakePlayer = new FakeBukkitServerPlayer(this.plugin); fakePlayer.setPlayer(player); @@ -1862,13 +1875,10 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes public void onPacketSend(NetWorkUser user, NMSPacketEvent event, Object packet) { List cachedUpdateTags = BukkitBlockManager.instance().cachedUpdateTags(); if (cachedUpdateTags.isEmpty()) return; - Map tags; - try { - tags = (Map) NetworkReflections.field$ClientboundUpdateTagsPacket$tags.get(packet); - } catch (Throwable e) { - CraftEngine.instance().logger().warn("Failed to get tags from ClientboundUpdateTagsPacket", e); - return; - } + Map tags = FastNMS.INSTANCE.field$ClientboundUpdateTagsPacket$tags(packet); + // 已经替换过了 + if (tags instanceof MarkedHashMap) return; + // 需要虚假的block if (tags.get(MRegistries.BLOCK) == null) return; event.replacePacket(TagUtils.createUpdateTagsPacket(Map.of(MRegistries.BLOCK, cachedUpdateTags), tags)); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/TagUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/TagUtils.java index 51e2887d6..9f82073e8 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/TagUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/TagUtils.java @@ -5,6 +5,7 @@ import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.core.util.FriendlyByteBuf; +import net.momirealms.craftengine.core.util.MarkedHashMap; import java.util.ArrayList; import java.util.HashMap; @@ -15,6 +16,9 @@ public final class TagUtils { private TagUtils() {} + public record TagEntry(int id, List tags) { + } + /** * 构建模拟标签更新数据包(用于向客户端添加虚拟标签) * @@ -39,57 +43,8 @@ public final class TagUtils { * * @return 可发送给客户端的 ClientboundUpdateTagsPacket 数据包对象 */ - @SuppressWarnings("unchecked") - public static Object createUpdateTagsPacket(Map> tags) { - Map registriesNetworkPayload = (Map) FastNMS.INSTANCE.method$TagNetworkSerialization$serializeTagsToNetwork(); - Map modified = new HashMap<>(); - for (Map.Entry payload : registriesNetworkPayload.entrySet()) { - List overrides = tags.get(payload.getKey()); - if (overrides == null || overrides.isEmpty()) { - modified.put(payload.getKey(), payload.getValue()); - continue; - } - FriendlyByteBuf deserializeBuf = new FriendlyByteBuf(Unpooled.buffer()); - FastNMS.INSTANCE.method$TagNetworkSerialization$NetworkPayload$write(payload.getValue(), deserializeBuf); - Map originalTags = deserializeBuf.readMap( - FriendlyByteBuf::readUtf, - FriendlyByteBuf::readIntIdList - ); - Map> reversedTags = new HashMap<>(); - for (Map.Entry tagEntry : originalTags.entrySet()) { - for (int id : tagEntry.getValue()) { - reversedTags.computeIfAbsent(id, k -> new ArrayList<>()).add(tagEntry.getKey()); - } - } - for (TagEntry tagEntry : overrides) { - reversedTags.remove(tagEntry.id); - for (String tag : tagEntry.tags) { - reversedTags.computeIfAbsent(tagEntry.id, k -> new ArrayList<>()).add(tag); - } - } - Map processedTags = new HashMap<>(); - for (Map.Entry> tagEntry : reversedTags.entrySet()) { - for (String tag : tagEntry.getValue()) { - processedTags.computeIfAbsent(tag, k -> new IntArrayList()).addLast(tagEntry.getKey()); - } - } - FriendlyByteBuf serializeBuf = new FriendlyByteBuf(Unpooled.buffer()); - serializeBuf.writeMap(processedTags, - FriendlyByteBuf::writeUtf, - FriendlyByteBuf::writeIntIdList - ); - Object mergedPayload = FastNMS.INSTANCE.method$TagNetworkSerialization$NetworkPayload$read(serializeBuf); - modified.put(payload.getKey(), mergedPayload); - } - return FastNMS.INSTANCE.constructor$ClientboundUpdateTagsPacket(modified); - } - - public record TagEntry(int id, List tags) { - } - - public static Object createUpdateTagsPacket(Map> tags, Map existingTags) { - Map modified = new HashMap<>(); + Map modified = new MarkedHashMap<>(); for (Map.Entry payload : existingTags.entrySet()) { List overrides = tags.get(payload.getKey()); if (overrides == null || overrides.isEmpty()) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/AbstractBlockManager.java b/core/src/main/java/net/momirealms/craftengine/core/block/AbstractBlockManager.java index fffa626dd..59941bb1f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/AbstractBlockManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/AbstractBlockManager.java @@ -143,7 +143,7 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem @Override public void delayedLoad() { this.initSuggestions(); - this.resendTags(); + this.updateTags(); this.processSounds(); this.clearCache(); } @@ -232,7 +232,7 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem public abstract BlockBehavior createBlockBehavior(CustomBlock customBlock, List> behaviorConfig); - protected abstract void resendTags(); + protected abstract void updateTags(); protected abstract boolean isVanillaBlock(Key id); diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java index c72a2f0b2..918c4dcb5 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java @@ -184,6 +184,8 @@ public abstract class CraftEngine implements Plugin { delayedLoadTasks.add(CompletableFuture.runAsync(() -> this.recipeManager.delayedLoad(), this.scheduler.async())); } CompletableFutures.allOf(delayedLoadTasks).join(); + // 重新发送tags,需要等待tags更新完成 + this.networkManager.delayedLoad(); long time2 = System.currentTimeMillis(); asyncTime = time2 - time1; } finally { diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/MarkedHashMap.java b/core/src/main/java/net/momirealms/craftengine/core/util/MarkedHashMap.java new file mode 100644 index 000000000..5acda9dda --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/util/MarkedHashMap.java @@ -0,0 +1,6 @@ +package net.momirealms.craftengine.core.util; + +import java.util.HashMap; + +public class MarkedHashMap extends HashMap { +} diff --git a/gradle.properties b/gradle.properties index 6c85cac44..f70a1caa7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -49,7 +49,7 @@ byte_buddy_version=1.17.8 ahocorasick_version=0.6.3 snake_yaml_version=2.5 anti_grief_version=1.0.4 -nms_helper_version=1.0.126 +nms_helper_version=1.0.127 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.34.5 From a5151767bbb2fbcc2c8c6b77d0562b1bd9520c8f Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Sat, 8 Nov 2025 05:53:50 +0800 Subject: [PATCH 25/37] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=BA=A7=E6=A4=85?= =?UTF-8?q?=E8=A1=8C=E4=B8=BA=E7=8E=A9=E5=AE=B6=E6=9C=9D=E5=90=91=E4=B8=8D?= =?UTF-8?q?=E6=AD=A3=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/block/entity/SeatBlockEntity.java | 14 +++++++++++++- .../bukkit/entity/seat/BukkitSeatManager.java | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/SeatBlockEntity.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/SeatBlockEntity.java index 360e58f38..8b520e63a 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/SeatBlockEntity.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/SeatBlockEntity.java @@ -59,11 +59,23 @@ public class SeatBlockEntity extends BlockEntity implements SeatOwner { } for (Seat seat : this.seats) { if (!seat.isOccupied()) { - if (seat.spawnSeat(player, new WorldPosition(super.world.world(), super.pos.x() + 0.5, super.pos.y(), super.pos.z() + 0.5, 0, 180 - yRot))) { + if (seat.spawnSeat(player, new WorldPosition(super.world.world(), super.pos.x() + 0.5, super.pos.y(), super.pos.z() + 0.5, 180 - yRot, getYRot()))) { return true; } } } return false; } + + private float getYRot() { + Property facing = super.blockState.owner().value().getProperty("facing"); + if (facing == null || facing.valueClass() != HorizontalDirection.class) return 0; + HorizontalDirection direction = (HorizontalDirection) super.blockState.get(facing); + return switch (direction) { + case NORTH -> 0; + case SOUTH -> 180; + case WEST -> 270; + case EAST -> 90; + }; + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/seat/BukkitSeatManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/seat/BukkitSeatManager.java index 9e45aa593..2e52d5564 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/seat/BukkitSeatManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/seat/BukkitSeatManager.java @@ -28,7 +28,7 @@ import org.jetbrains.annotations.NotNull; import java.io.IOException; -public class BukkitSeatManager implements SeatManager { +public class BukkitSeatManager implements SeatManager, Listener { private static BukkitSeatManager instance; public static final NamespacedKey SEAT_KEY = KeyUtils.toNamespacedKey(SeatManager.SEAT_KEY); public static final NamespacedKey SEAT_EXTRA_DATA_KEY = KeyUtils.toNamespacedKey(SeatManager.SEAT_EXTRA_DATA_KEY); From b9cee377d8d383752d70170c239009c410307e1a Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Sat, 8 Nov 2025 06:04:12 +0800 Subject: [PATCH 26/37] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=BA=A7=E6=A4=85?= =?UTF-8?q?=E8=A1=8C=E4=B8=BA=E7=8E=A9=E5=AE=B6=E6=9C=9D=E5=90=91=E4=B8=8D?= =?UTF-8?q?=E6=AD=A3=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/block/entity/SeatBlockEntity.java | 42 +++++-------------- 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/SeatBlockEntity.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/SeatBlockEntity.java index 8b520e63a..421e8f94e 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/SeatBlockEntity.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/SeatBlockEntity.java @@ -1,6 +1,5 @@ package net.momirealms.craftengine.bukkit.block.entity; -import net.momirealms.craftengine.bukkit.block.behavior.SeatBlockBehavior; import net.momirealms.craftengine.bukkit.entity.seat.BukkitSeat; import net.momirealms.craftengine.core.block.ImmutableBlockState; import net.momirealms.craftengine.core.block.entity.BlockEntity; @@ -14,8 +13,6 @@ import net.momirealms.craftengine.core.world.BlockPos; import net.momirealms.craftengine.core.world.WorldPosition; import net.momirealms.sparrow.nbt.CompoundTag; -import java.util.Optional; - public class SeatBlockEntity extends BlockEntity implements SeatOwner { private final Seat[] seats; @@ -41,41 +38,24 @@ public class SeatBlockEntity extends BlockEntity implements SeatOwner { } public boolean spawnSeat(Player player) { - Optional seatBehavior = super.blockState.behavior().getAs(SeatBlockBehavior.class); - if (seatBehavior.isEmpty()) { - return false; - } - float yRot = 0; - Property directionProperty = seatBehavior.get().directionProperty(); - if (directionProperty != null) { - HorizontalDirection direction = super.blockState.get(directionProperty); - if (direction == HorizontalDirection.NORTH) { - yRot = 180; - } else if (direction == HorizontalDirection.EAST) { - yRot = -90; - } else if (direction == HorizontalDirection.WEST) { - yRot = 90; - } + Property facing = super.blockState.owner().value().getProperty("facing"); + int yRot = 0; + if (facing != null && facing.valueClass() == HorizontalDirection.class) { + HorizontalDirection direction = (HorizontalDirection) super.blockState.get(facing); + yRot = switch (direction) { + case NORTH -> 0; + case SOUTH -> 180; + case WEST -> 270; + case EAST -> 90; + }; } for (Seat seat : this.seats) { if (!seat.isOccupied()) { - if (seat.spawnSeat(player, new WorldPosition(super.world.world(), super.pos.x() + 0.5, super.pos.y(), super.pos.z() + 0.5, 180 - yRot, getYRot()))) { + if (seat.spawnSeat(player, new WorldPosition(super.world.world(), super.pos.x() + 0.5, super.pos.y(), super.pos.z() + 0.5, 0, yRot))) { return true; } } } return false; } - - private float getYRot() { - Property facing = super.blockState.owner().value().getProperty("facing"); - if (facing == null || facing.valueClass() != HorizontalDirection.class) return 0; - HorizontalDirection direction = (HorizontalDirection) super.blockState.get(facing); - return switch (direction) { - case NORTH -> 0; - case SOUTH -> 180; - case WEST -> 270; - case EAST -> 90; - }; - } } From d81331df913e9dd43cce4f5290ef07d254092921 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Sat, 8 Nov 2025 16:21:02 +0800 Subject: [PATCH 27/37] Update AbstractPackManager.java --- .../momirealms/craftengine/core/pack/AbstractPackManager.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java index 776829a2f..6981623e8 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java @@ -40,6 +40,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.yaml.snakeyaml.LoaderOptions; import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.parser.ParserException; import org.yaml.snakeyaml.scanner.ScannerException; import javax.imageio.ImageIO; @@ -619,6 +620,9 @@ public abstract class AbstractPackManager implements PackManager { AbstractPackManager.this.plugin.logger().severe("Error found while reading config file: " + path, e); } return FileVisitResult.CONTINUE; + } catch (ParserException e) { + AbstractPackManager.this.plugin.logger().severe("Invalid YAML file found: " + path + ".\n" + e.getMessage() + "\nIt is recommended to use Visual Studio Code as your YAML editor to fix problems more quickly."); + return FileVisitResult.CONTINUE; } catch (LocalizedException e) { e.setArgument(0, path.toString()); TranslationManager.instance().log(e.node(), e.arguments()); From a2e5443ecc6140c296ff84aecc18987b2b6d6de0 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Sat, 8 Nov 2025 16:58:57 +0800 Subject: [PATCH 28/37] Update World.java --- .../java/net/momirealms/craftengine/core/world/World.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/World.java b/core/src/main/java/net/momirealms/craftengine/core/world/World.java index 6bf1e2eed..c8b94cdc4 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/World.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/World.java @@ -39,6 +39,14 @@ public interface World { this.setBlockAt(x, y, z, blockState.customBlockState(), flags); } + default void setBlockAt(BlockPos pos, BlockStateWrapper blockState, int flags) { + this.setBlockAt(pos.x(), pos.y(), pos.z(), blockState, flags); + } + + default void setBlockAt(BlockPos pos, ImmutableBlockState blockState, int flags) { + this.setBlockAt(pos.x(), pos.y(), pos.z(), blockState, flags); + } + String name(); Path directory(); From 4fa34bf3666b3054367ef976944bb77393db481f Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Sat, 8 Nov 2025 17:44:39 +0800 Subject: [PATCH 29/37] =?UTF-8?q?=E6=B7=BB=E5=8A=A0apply=5Fdata=E6=88=98?= =?UTF-8?q?=E5=88=A9=E5=93=81=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/translations/en.yml | 1 + .../core/item/context/UseOnContext.java | 4 ++ .../core/loot/function/ApplyDataFunction.java | 58 +++++++++++++++++++ .../core/loot/function/LootFunctions.java | 2 + 4 files changed, 65 insertions(+) create mode 100644 core/src/main/java/net/momirealms/craftengine/core/loot/function/ApplyDataFunction.java diff --git a/common-files/src/main/resources/translations/en.yml b/common-files/src/main/resources/translations/en.yml index 13f426037..93b5e5c72 100644 --- a/common-files/src/main/resources/translations/en.yml +++ b/common-files/src/main/resources/translations/en.yml @@ -374,6 +374,7 @@ warning.config.loot_table.function.apply_bonus.missing_enchantment: "Iss warning.config.loot_table.function.apply_bonus.missing_formula: "Issue found in file - '' has a misconfigured loot table, function 'apply_bonus' is missing the required 'formula' argument." warning.config.loot_table.function.drop_exp.missing_count: "Issue found in file - '' has a misconfigured loot table, function 'drop_exp' is missing the required 'count' argument." warning.config.loot_table.function.set_count.missing_count: "Issue found in file - '' has a misconfigured loot table, function 'set_count' is missing the required 'count' argument." +warning.config.loot_table.function.apply_data.missing_data: "Issue found in file - '' has a misconfigured loot table, function 'apply_data' is missing the required 'data' argument." warning.config.loot_table.entry.missing_type: "Issue found in file - '' has a misconfigured loot table, one of the entries is missing the required 'type' argument." warning.config.loot_table.entry.invalid_type: "Issue found in file - '' has a misconfigured loot table, one of the entries is using an invalid entry type ''." warning.config.loot_table.entry.exp.missing_count: "Issue found in file - '' has a misconfigured loot table, entry 'exp' is missing the required 'count' argument." diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/context/UseOnContext.java b/core/src/main/java/net/momirealms/craftengine/core/item/context/UseOnContext.java index dc59e38aa..21a4ae92e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/context/UseOnContext.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/context/UseOnContext.java @@ -73,6 +73,10 @@ public class UseOnContext { return this.level; } + public World getWorld() { + return this.level; + } + public Direction getHorizontalDirection() { return this.player == null ? Direction.NORTH : this.player.getDirection(); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/loot/function/ApplyDataFunction.java b/core/src/main/java/net/momirealms/craftengine/core/loot/function/ApplyDataFunction.java new file mode 100644 index 000000000..168d9e6fa --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/loot/function/ApplyDataFunction.java @@ -0,0 +1,58 @@ +package net.momirealms.craftengine.core.loot.function; + +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.item.recipe.result.ApplyItemDataPostProcessor; +import net.momirealms.craftengine.core.loot.LootConditions; +import net.momirealms.craftengine.core.loot.LootContext; +import net.momirealms.craftengine.core.plugin.context.Condition; +import net.momirealms.craftengine.core.plugin.context.number.NumberProvider; +import net.momirealms.craftengine.core.plugin.context.number.NumberProviders; +import net.momirealms.craftengine.core.registry.BuiltInRegistries; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; + +import java.util.*; + +public class ApplyDataFunction extends AbstractLootConditionalFunction { + public static final Factory FACTORY = new Factory<>(); + private final ItemDataModifier[] modifiers; + + public ApplyDataFunction(List> conditions, ItemDataModifier[] modifiers) { + super(conditions); + this.modifiers = modifiers; + } + + @Override + public Key type() { + return LootFunctions.APPLY_DATA; + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + @Override + protected Item applyInternal(Item item, LootContext context) { + ItemBuildContext ctx = ItemBuildContext.of(context.player()); + for (ItemDataModifier modifier : this.modifiers) { + item = modifier.apply(item, ctx); + } + return item; + } + + public static class Factory implements LootFunctionFactory { + @SuppressWarnings("unchecked") + @Override + public LootFunction create(Map arguments) { + List> modifiers = new ArrayList<>(); + Map data = ResourceConfigUtils.getAsMap(ResourceConfigUtils.requireNonNullOrThrow(arguments.get("data"), "warning.config.loot_table.function.apply_data.missing_data"), "data"); + for (Map.Entry entry : data.entrySet()) { + Optional.ofNullable(BuiltInRegistries.ITEM_DATA_MODIFIER_FACTORY.getValue(Key.withDefaultNamespace(entry.getKey(), Key.DEFAULT_NAMESPACE))) + .ifPresent(factory -> modifiers.add(factory.create(entry.getValue()))); + } + List> conditions = Optional.ofNullable(arguments.get("conditions")) + .map(it -> LootConditions.fromMapList((List>) it)) + .orElse(Collections.emptyList()); + return new ApplyDataFunction<>(conditions, modifiers.toArray(new ItemDataModifier[0])); + } + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/loot/function/LootFunctions.java b/core/src/main/java/net/momirealms/craftengine/core/loot/function/LootFunctions.java index c9d221c95..854e741e1 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/loot/function/LootFunctions.java +++ b/core/src/main/java/net/momirealms/craftengine/core/loot/function/LootFunctions.java @@ -17,6 +17,7 @@ import java.util.function.BiFunction; public class LootFunctions { public static final Key APPLY_BONUS = Key.from("craftengine:apply_bonus"); + public static final Key APPLY_DATA = Key.from("craftengine:apply_data"); public static final Key SET_COUNT = Key.from("craftengine:set_count"); public static final Key EXPLOSION_DECAY = Key.from("craftengine:explosion_decay"); public static final Key DROP_EXP = Key.from("craftengine:drop_exp"); @@ -24,6 +25,7 @@ public class LootFunctions { static { register(SET_COUNT, SetCountFunction.FACTORY); + register(APPLY_DATA, ApplyDataFunction.FACTORY); register(EXPLOSION_DECAY, ExplosionDecayFunction.FACTORY); register(APPLY_BONUS, ApplyBonusCountFunction.FACTORY); register(DROP_EXP, DropExpFunction.FACTORY); From 59362ea5cf955999a6bd241cf828768f32bef948 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Sat, 8 Nov 2025 18:04:17 +0800 Subject: [PATCH 30/37] Update safe_block.yml --- .../resources/default/configuration/blocks/safe_block.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/safe_block.yml b/common-files/src/main/resources/resources/default/configuration/blocks/safe_block.yml index 63b13e353..ff538a949 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/safe_block.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/safe_block.yml @@ -58,6 +58,7 @@ items: front: minecraft:block/custom/safe_block_front side: minecraft:block/custom/safe_block_side top: minecraft:block/custom/safe_block_top + bottom: minecraft:block/custom/safe_block_bottom east_open: auto-state: note_block model: @@ -69,6 +70,7 @@ items: front: minecraft:block/custom/safe_block_front_open side: minecraft:block/custom/safe_block_side top: minecraft:block/custom/safe_block_top + bottom: minecraft:block/custom/safe_block_bottom north: auto-state: note_block model: From 1565d342db12dc1b1ec7376e2435c3a2cba92396 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Sat, 8 Nov 2025 18:59:17 +0800 Subject: [PATCH 31/37] Update SingleItemLootEntryContainer.java --- .../core/loot/entry/SingleItemLootEntryContainer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/net/momirealms/craftengine/core/loot/entry/SingleItemLootEntryContainer.java b/core/src/main/java/net/momirealms/craftengine/core/loot/entry/SingleItemLootEntryContainer.java index 4eaffd83c..57929f117 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/loot/entry/SingleItemLootEntryContainer.java +++ b/core/src/main/java/net/momirealms/craftengine/core/loot/entry/SingleItemLootEntryContainer.java @@ -43,7 +43,7 @@ public class SingleItemLootEntryContainer extends AbstractSingleLootEntryCont @SuppressWarnings("unchecked") @Override public LootEntryContainer create(Map arguments) { - String itemObj = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("item"), "warning.config.loot_table.entry.item.missing_item"); + String itemObj = ResourceConfigUtils.requireNonEmptyStringOrThrow(ResourceConfigUtils.get(arguments, "item", "id"), "warning.config.loot_table.entry.item.missing_item"); Key item = Key.from(itemObj); int weight = ResourceConfigUtils.getAsInt(arguments.getOrDefault("weight", 1), "weight"); int quality = ResourceConfigUtils.getAsInt(arguments.getOrDefault("quality", 0), "quality"); From b834e981c25f76be4499056304b4f5e28991f4d0 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Sat, 8 Nov 2025 21:40:17 +0800 Subject: [PATCH 32/37] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20item=20=E6=B8=B2?= =?UTF-8?q?=E6=9F=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/block/BukkitBlockManager.java | 4 + .../BukkitBlockEntityElementConfigs.java | 1 + .../element/ItemBlockEntityElement.java | 65 ++++++++++++++++ .../element/ItemBlockEntityElementConfig.java | 77 +++++++++++++++++++ .../ItemDisplayBlockEntityElement.java | 2 +- .../TextDisplayBlockEntityElement.java | 2 +- .../bukkit/entity/data/ItemEntityData.java | 11 +++ .../plugin/injector/BlockGenerator.java | 8 ++ .../element/BlockEntityElementConfigs.java | 1 + 9 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemBlockEntityElement.java create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemBlockEntityElementConfig.java create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/ItemEntityData.java diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java index 01d66a69d..10c77c589 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java @@ -290,6 +290,10 @@ public final class BukkitBlockManager extends AbstractBlockManager { this.burnOdds.put(nmsBlock, settings.fireSpreadChance()); this.burnableBlocks.add(nmsBlock); } + + Key vanillaBlockId = state.vanillaBlockState().ownerId(); + BlockGenerator.field$CraftEngineBlock$isNoteBlock().set(nmsBlock, vanillaBlockId.equals(BlockKeys.NOTE_BLOCK)); + BlockGenerator.field$CraftEngineBlock$isTripwire().set(nmsBlock, vanillaBlockId.equals(BlockKeys.TRIPWIRE)); } catch (ReflectiveOperationException e) { this.plugin.logger().warn("Failed to apply platform block settings for block state " + state, e); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/BukkitBlockEntityElementConfigs.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/BukkitBlockEntityElementConfigs.java index 8553a7c56..ee182e392 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/BukkitBlockEntityElementConfigs.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/BukkitBlockEntityElementConfigs.java @@ -7,6 +7,7 @@ public class BukkitBlockEntityElementConfigs extends BlockEntityElementConfigs { static { register(ITEM_DISPLAY, ItemDisplayBlockEntityElementConfig.FACTORY); register(TEXT_DISPLAY, TextDisplayBlockEntityElementConfig.FACTORY); + register(ITEM, ItemBlockEntityElementConfig.FACTORY); } private BukkitBlockEntityElementConfigs() {} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemBlockEntityElement.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemBlockEntityElement.java new file mode 100644 index 000000000..7cf886977 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemBlockEntityElement.java @@ -0,0 +1,65 @@ +package net.momirealms.craftengine.bukkit.block.entity.renderer.element; + +import it.unimi.dsi.fastutil.ints.IntList; +import net.momirealms.craftengine.bukkit.nms.FastNMS; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MEntityTypes; +import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityElement; +import net.momirealms.craftengine.core.entity.player.Player; +import net.momirealms.craftengine.core.world.BlockPos; +import org.joml.Vector3f; + +import java.util.List; +import java.util.UUID; + +public class ItemBlockEntityElement implements BlockEntityElement { + public final ItemBlockEntityElementConfig config; + public final Object cachedSpawnPacket1; + public final Object cachedSpawnPacket2; + public final Object cachedRidePacket; + public final Object cachedDespawnPacket; + public final Object cachedUpdatePosPacket; + public final int entityId1; + public final int entityId2; + + public ItemBlockEntityElement(ItemBlockEntityElementConfig config, BlockPos pos) { + this(config, pos, CoreReflections.instance$Entity$ENTITY_COUNTER.incrementAndGet(), CoreReflections.instance$Entity$ENTITY_COUNTER.incrementAndGet(), false); + } + + public ItemBlockEntityElement(ItemBlockEntityElementConfig config, BlockPos pos, int entityId1, int entityId2, boolean posChanged) { + this.config = config; + Vector3f position = config.position(); + this.cachedSpawnPacket1 = FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( + entityId1, UUID.randomUUID(), pos.x() + position.x, pos.y() + position.y, pos.z() + position.z, + 0, 0, MEntityTypes.ITEM_DISPLAY, 0, CoreReflections.instance$Vec3$Zero, 0 + ); + this.cachedSpawnPacket2 = FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( + entityId2, UUID.randomUUID(), pos.x() + position.x, pos.y() + position.y, pos.z() + position.z, + 0, 0, MEntityTypes.ITEM, 0, CoreReflections.instance$Vec3$Zero, 0 + ); + this.cachedRidePacket = FastNMS.INSTANCE.constructor$ClientboundSetPassengersPacket(entityId1, entityId2); + this.cachedDespawnPacket = FastNMS.INSTANCE.constructor$ClientboundRemoveEntitiesPacket(IntList.of(entityId1, entityId2)); + this.entityId1 = entityId1; + this.entityId2 = entityId2; + this.cachedUpdatePosPacket = posChanged ? FastNMS.INSTANCE.constructor$ClientboundEntityPositionSyncPacket(this.entityId1, pos.x() + position.x, pos.y() + position.y, pos.z() + position.z, 0, 0, false) : null; + } + + @Override + public void hide(Player player) { + player.sendPacket(this.cachedDespawnPacket, false); + } + + @Override + public void show(Player player) { + player.sendPackets(List.of(this.cachedSpawnPacket1, this.cachedSpawnPacket2, this.cachedRidePacket, FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId2, this.config.metadataValues(player))), false); + } + + @Override + public void transform(Player player) { + if (this.cachedUpdatePosPacket != null) { + player.sendPackets(List.of(this.cachedUpdatePosPacket, FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId2, this.config.metadataValues(player))), false); + } else { + player.sendPacket(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId2, this.config.metadataValues(player)), false); + } + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemBlockEntityElementConfig.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemBlockEntityElementConfig.java new file mode 100644 index 000000000..96873d757 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemBlockEntityElementConfig.java @@ -0,0 +1,77 @@ +package net.momirealms.craftengine.bukkit.block.entity.renderer.element; + +import net.momirealms.craftengine.bukkit.entity.data.ItemEntityData; +import net.momirealms.craftengine.bukkit.item.BukkitItemManager; +import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityElement; +import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityElementConfig; +import net.momirealms.craftengine.core.block.entity.render.element.BlockEntityElementConfigFactory; +import net.momirealms.craftengine.core.entity.player.Player; +import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import net.momirealms.craftengine.core.world.BlockPos; +import net.momirealms.craftengine.core.world.World; +import org.joml.Vector3f; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +public class ItemBlockEntityElementConfig implements BlockEntityElementConfig { + public static final Factory FACTORY = new Factory(); + private final Function> lazyMetadataPacket; + private final Function> item; + private final Vector3f position; + + public ItemBlockEntityElementConfig(Function> item, Vector3f position) { + this.item = item; + this.position = position; + this.lazyMetadataPacket = player -> { + List dataValues = new ArrayList<>(); + ItemEntityData.Item.addEntityDataIfNotDefaultValue(item.apply(player).getLiteralObject(), dataValues); + ItemEntityData.NoGravity.addEntityDataIfNotDefaultValue(true, dataValues); + return dataValues; + }; + } + + @Override + public ItemBlockEntityElement create(World world, BlockPos pos) { + return new ItemBlockEntityElement(this, pos); + } + + @Override + public ItemBlockEntityElement create(World world, BlockPos pos, ItemBlockEntityElement previous) { + return new ItemBlockEntityElement(this, pos, previous.entityId1, previous.entityId2, !previous.config.position.equals(this.position)); + } + + @Override + public Class elementClass() { + return ItemBlockEntityElement.class; + } + + public Vector3f position() { + return position; + } + + public Item item(Player player) { + return this.item.apply(player); + } + + public List metadataValues(Player player) { + return this.lazyMetadataPacket.apply(player); + } + + public static class Factory implements BlockEntityElementConfigFactory { + + @SuppressWarnings("unchecked") + @Override + public BlockEntityElementConfig create(Map arguments) { + Key itemId = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("item"), "warning.config.block.state.entity_renderer.item_display.missing_item")); + return (BlockEntityElementConfig) new ItemBlockEntityElementConfig( + player -> BukkitItemManager.instance().createWrappedItem(itemId, player), + ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("position", 0.5f), "position") + ); + } + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElement.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElement.java index 4159f41d7..558e56ff9 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElement.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/ItemDisplayBlockEntityElement.java @@ -42,7 +42,7 @@ public class ItemDisplayBlockEntityElement implements BlockEntityElement { @Override public void show(Player player) { - player.sendPackets(List.of(this.cachedSpawnPacket, FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player))), true); + player.sendPackets(List.of(this.cachedSpawnPacket, FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player))), false); } @Override diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElement.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElement.java index de3c7a644..9cefef8eb 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElement.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/element/TextDisplayBlockEntityElement.java @@ -42,7 +42,7 @@ public class TextDisplayBlockEntityElement implements BlockEntityElement { @Override public void show(Player player) { - player.sendPackets(List.of(this.cachedSpawnPacket, FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player))), true); + player.sendPackets(List.of(this.cachedSpawnPacket, FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(this.entityId, this.config.metadataValues(player))), false); } @Override diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/ItemEntityData.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/ItemEntityData.java new file mode 100644 index 000000000..a31b2272b --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/ItemEntityData.java @@ -0,0 +1,11 @@ +package net.momirealms.craftengine.bukkit.entity.data; + +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; + +public class ItemEntityData extends BaseEntityData { + public static final ItemEntityData Item = new ItemEntityData<>(ItemEntityData.class, EntityDataValue.Serializers$ITEM_STACK, CoreReflections.instance$ItemStack$EMPTY); + + public ItemEntityData(Class clazz, Object serializer, T defaultValue) { + super(clazz, serializer, defaultValue); + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockGenerator.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockGenerator.java index 70f1823bb..b757fae76 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockGenerator.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockGenerator.java @@ -201,6 +201,14 @@ public final class BlockGenerator { field$CraftEngineBlock$isTripwire = clazz$CraftEngineBlock.getField("isClientSideTripwire"); } + public static Field field$CraftEngineBlock$isNoteBlock() { + return field$CraftEngineBlock$isNoteBlock; + } + + public static Field field$CraftEngineBlock$isTripwire() { + return field$CraftEngineBlock$isTripwire; + } + public static DelegatingBlock generateBlock(Key blockId) throws Throwable { ObjectHolder behaviorHolder = new ObjectHolder<>(EmptyBlockBehavior.INSTANCE); ObjectHolder shapeHolder = new ObjectHolder<>(STONE_SHAPE); diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/element/BlockEntityElementConfigs.java b/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/element/BlockEntityElementConfigs.java index 910c56f56..1dabfa3be 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/element/BlockEntityElementConfigs.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/element/BlockEntityElementConfigs.java @@ -13,6 +13,7 @@ import java.util.Optional; public abstract class BlockEntityElementConfigs { public static final Key ITEM_DISPLAY = Key.of("craftengine:item_display"); public static final Key TEXT_DISPLAY = Key.of("craftengine:text_display"); + public static final Key ITEM = Key.of("craftengine:item"); public static void register(Key key, BlockEntityElementConfigFactory type) { ((WritableRegistry) BuiltInRegistries.BLOCK_ENTITY_ELEMENT_TYPE) From 7dbd8073e81d3858b7002a97781fbcf26fde99a5 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Sat, 8 Nov 2025 22:18:02 +0800 Subject: [PATCH 33/37] Update gradle.properties --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index f70a1caa7..0ec0adef5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.65.5 +project_version=0.0.65.6 config_version=53 lang_version=37 project_group=net.momirealms From 939db3b3b36501f6886ab6263533ad044d4a1d58 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Sat, 8 Nov 2025 22:21:00 +0800 Subject: [PATCH 34/37] =?UTF-8?q?=E5=A2=9E=E5=BC=BAdrop=5Floot=E5=87=BD?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../context/function/DropLootFunction.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/DropLootFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/DropLootFunction.java index 216c1c511..8fa3930ac 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/DropLootFunction.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/DropLootFunction.java @@ -10,6 +10,7 @@ import net.momirealms.craftengine.core.plugin.context.number.NumberProviders; import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; import net.momirealms.craftengine.core.world.World; import net.momirealms.craftengine.core.world.WorldPosition; @@ -22,13 +23,15 @@ public class DropLootFunction extends AbstractConditionalFu private final NumberProvider y; private final NumberProvider z; private final LootTable lootTable; + private final boolean toInv; - public DropLootFunction(NumberProvider x, NumberProvider y, NumberProvider z, LootTable lootTable, List> predicates) { + public DropLootFunction(List> predicates, NumberProvider x, NumberProvider y, NumberProvider z, LootTable lootTable, boolean toInv) { super(predicates); this.x = x; this.y = y; this.z = z; this.lootTable = lootTable; + this.toInv = toInv; } @Override @@ -39,8 +42,14 @@ public class DropLootFunction extends AbstractConditionalFu WorldPosition position = new WorldPosition(world, x.getDouble(ctx), y.getDouble(ctx), z.getDouble(ctx)); Player player = ctx.getOptionalParameter(DirectContextParameters.PLAYER).orElse(null); List> items = lootTable.getRandomItems(ctx.contexts(), world, player); - for (Item item : items) { - world.dropItemNaturally(position, item); + if (this.toInv && player != null) { + for (Item item : items) { + player.giveItem(item); + } + } else { + for (Item item : items) { + world.dropItemNaturally(position, item); + } } } } @@ -62,7 +71,8 @@ public class DropLootFunction extends AbstractConditionalFu NumberProvider y = NumberProviders.fromObject(arguments.getOrDefault("y", "")); NumberProvider z = NumberProviders.fromObject(arguments.getOrDefault("z", "")); LootTable loots = LootTable.fromMap(MiscUtils.castToMap(arguments.get("loot"), true)); - return new DropLootFunction<>(x, y, z, loots, getPredicates(arguments)); + boolean toInv = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("to-inventory", false), "to-inventory"); + return new DropLootFunction<>(getPredicates(arguments), x, y, z, loots, toInv); } } } From 74d20d84836c7f23b7ed21af665a71158426a257 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Sun, 9 Nov 2025 14:59:46 +0800 Subject: [PATCH 35/37] =?UTF-8?q?=E9=A2=84=E9=98=B2=E6=9C=AA=E5=90=AF?= =?UTF-8?q?=E7=94=A8=E5=9F=BA=E4=BA=8E=E7=BA=B9=E9=A5=B0=E7=9B=94=E7=94=B2?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E9=94=81=E9=93=BE=E7=94=B2=E4=BA=A7=E7=94=9F?= =?UTF-8?q?=E7=9A=84=E7=BD=91=E7=BB=9C=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../item/factory/ComponentItemFactory1_20_5.java | 15 +++++++++++---- .../resources/resources/legacy_armor/pack.yml | 4 +--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_20_5.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_20_5.java index 7a24b32f8..01539c1b0 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_20_5.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_20_5.java @@ -501,10 +501,17 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory=1.21.2: false - $$<1.21.2: true +enable: false From 8809c354db91207d8a12c5999656375eab1b170e Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Sun, 9 Nov 2025 15:10:22 +0800 Subject: [PATCH 36/37] =?UTF-8?q?=E9=BB=98=E8=AE=A4=E4=BD=BF=E7=94=A8l10n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../configuration/blocks/amethyst_torch.yml | 6 ++-- .../configuration/blocks/chessboard_block.yml | 2 +- .../configuration/blocks/chinese_lantern.yml | 2 +- .../configuration/blocks/copper_coil.yml | 2 +- .../blocks/ender_pearl_flower.yml | 2 +- .../configuration/blocks/fairy_flower.yml | 2 +- .../configuration/blocks/flame_cane.yml | 2 +- .../configuration/blocks/gunpowder_block.yml | 4 +-- .../configuration/blocks/hami_melon.yml | 6 ++-- .../configuration/blocks/magma_plant.yml | 2 +- .../configuration/blocks/netherite_anvil.yml | 2 +- .../configuration/blocks/palm_tree.yml | 30 +++++++++---------- .../default/configuration/blocks/pebble.yml | 2 +- .../default/configuration/blocks/reed.yml | 2 +- .../configuration/blocks/safe_block.yml | 4 +-- .../default/configuration/blocks/sofa.yml | 4 +-- .../configuration/blocks/table_lamp.yml | 2 +- .../configuration/blocks/topaz_ore.yml | 6 ++-- .../default/configuration/categories.yml | 10 +++---- .../resources/default/configuration/emoji.yml | 2 +- .../default/configuration/furniture/bench.yml | 2 +- .../configuration/furniture/flower_basket.yml | 2 +- .../configuration/furniture/wooden_chair.yml | 2 +- .../default/configuration/items/cap.yml | 2 +- .../configuration/items/flame_elytra.yml | 2 +- .../configuration/items/topaz_armor.yml | 2 +- .../configuration/items/topaz_tool_weapon.yml | 20 ++++++------- 27 files changed, 63 insertions(+), 63 deletions(-) diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/amethyst_torch.yml b/common-files/src/main/resources/resources/default/configuration/blocks/amethyst_torch.yml index 773ea9c4e..5abdab95c 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/amethyst_torch.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/amethyst_torch.yml @@ -2,7 +2,7 @@ items: default:amethyst_torch: material: nether_brick data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/amethyst_torch @@ -20,7 +20,7 @@ items: default:amethyst_standing_torch: material: nether_brick data: - item-name: + item-name: model: type: minecraft:model path: minecraft:block/custom/amethyst_torch @@ -31,7 +31,7 @@ items: default:amethyst_wall_torch: material: nether_brick data: - item-name: + item-name: model: type: minecraft:model path: minecraft:block/custom/amethyst_wall_torch diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/chessboard_block.yml b/common-files/src/main/resources/resources/default/configuration/blocks/chessboard_block.yml index 7e36d6d45..cb6bfdb18 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/chessboard_block.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/chessboard_block.yml @@ -2,7 +2,7 @@ items: default:chessboard_block: material: nether_brick data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/chessboard_block diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/chinese_lantern.yml b/common-files/src/main/resources/resources/default/configuration/blocks/chinese_lantern.yml index 420809bc8..1dadb3500 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/chinese_lantern.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/chinese_lantern.yml @@ -2,7 +2,7 @@ items: default:chinese_lantern: material: nether_brick data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/chinese_lantern diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/copper_coil.yml b/common-files/src/main/resources/resources/default/configuration/blocks/copper_coil.yml index 9d9b8bf83..7615f1fb6 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/copper_coil.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/copper_coil.yml @@ -2,7 +2,7 @@ items: default:copper_coil: material: nether_brick data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/copper_coil diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/ender_pearl_flower.yml b/common-files/src/main/resources/resources/default/configuration/blocks/ender_pearl_flower.yml index 0847ee653..258f99c92 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/ender_pearl_flower.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/ender_pearl_flower.yml @@ -2,7 +2,7 @@ items: default:ender_pearl_flower_seeds: material: nether_brick data: - item-name: + item-name: model: template: default:model/simplified_generated arguments: diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/fairy_flower.yml b/common-files/src/main/resources/resources/default/configuration/blocks/fairy_flower.yml index ef42b7638..08debd5e8 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/fairy_flower.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/fairy_flower.yml @@ -2,7 +2,7 @@ items: default:fairy_flower: material: nether_brick data: - item-name: + item-name: model: template: default:model/simplified_generated arguments: diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/flame_cane.yml b/common-files/src/main/resources/resources/default/configuration/blocks/flame_cane.yml index 4213b62bd..dd50822f0 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/flame_cane.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/flame_cane.yml @@ -2,7 +2,7 @@ items: default:flame_cane: material: nether_brick data: - item-name: + item-name: model: template: default:model/simplified_generated arguments: diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/gunpowder_block.yml b/common-files/src/main/resources/resources/default/configuration/blocks/gunpowder_block.yml index e114b183c..17bf82ce5 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/gunpowder_block.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/gunpowder_block.yml @@ -2,7 +2,7 @@ items: default:gunpowder_block: material: nether_brick data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/gunpowder_block @@ -37,7 +37,7 @@ items: default:solid_gunpowder_block: material: nether_brick data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/solid_gunpowder_block diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/hami_melon.yml b/common-files/src/main/resources/resources/default/configuration/blocks/hami_melon.yml index 03592440a..67de31a05 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/hami_melon.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/hami_melon.yml @@ -2,7 +2,7 @@ items: default:hami_melon_slice: material: melon_slice data: - item-name: + item-name: $$>=1.20.5: food: nutrition: 2 @@ -20,7 +20,7 @@ items: default:hami_melon: material: nether_brick data: - item-name: + item-name: model: path: minecraft:item/custom/hami_melon generation: @@ -31,7 +31,7 @@ items: default:hami_melon_seeds: material: nether_brick data: - item-name: + item-name: model: template: default:model/simplified_generated arguments: diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/magma_plant.yml b/common-files/src/main/resources/resources/default/configuration/blocks/magma_plant.yml index 7eb0e196b..b608b57b9 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/magma_plant.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/magma_plant.yml @@ -6,7 +6,7 @@ items: arguments: path: minecraft:item/custom/magma_fruit data: - item-name: + item-name: $$>=1.20.5: food: nutrition: 3 diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/netherite_anvil.yml b/common-files/src/main/resources/resources/default/configuration/blocks/netherite_anvil.yml index 467ff359b..86fbecd35 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/netherite_anvil.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/netherite_anvil.yml @@ -2,7 +2,7 @@ items: default:netherite_anvil: material: nether_brick data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/netherite_anvil diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/palm_tree.yml b/common-files/src/main/resources/resources/default/configuration/blocks/palm_tree.yml index d628ff0d8..b3835f599 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/palm_tree.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/palm_tree.yml @@ -8,7 +8,7 @@ items: - minecraft:logs - minecraft:logs_that_burn data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/palm_log @@ -40,7 +40,7 @@ items: - minecraft:logs - minecraft:logs_that_burn data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/stripped_palm_log @@ -69,7 +69,7 @@ items: - minecraft:logs - minecraft:logs_that_burn data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/palm_wood @@ -101,7 +101,7 @@ items: - minecraft:logs - minecraft:logs_that_burn data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/stripped_palm_wood @@ -129,7 +129,7 @@ items: - minecraft:planks - minecraft:wooden_tool_materials data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/palm_planks @@ -153,7 +153,7 @@ items: settings: fuel-time: 100 data: - item-name: + item-name: lore: - "Requires the datapack tree configuration to function." - "If not configured, an oak tree will grow by default." @@ -197,7 +197,7 @@ items: default:palm_leaves: material: oak_leaves data: - item-name: + item-name: block-state: default:palm_leaves[persistent=true,waterlogged=false,distance=7] model: type: minecraft:model @@ -227,7 +227,7 @@ items: default:palm_trapdoor: material: nether_brick data: - item-name: + item-name: settings: fuel-time: 300 model: @@ -281,7 +281,7 @@ items: default:palm_door: material: nether_brick data: - item-name: + item-name: settings: fuel-time: 200 model: @@ -355,7 +355,7 @@ items: default:palm_fence_gate: material: nether_brick data: - item-name: + item-name: settings: fuel-time: 300 model: @@ -411,7 +411,7 @@ items: default:palm_slab: material: nether_brick data: - item-name: + item-name: settings: fuel-time: 150 model: @@ -462,7 +462,7 @@ items: generation: parent: minecraft:block/custom/palm_stairs data: - item-name: + item-name: settings: fuel-time: 300 behavior: @@ -511,7 +511,7 @@ items: generation: parent: minecraft:block/custom/palm_pressure_plate data: - item-name: + item-name: settings: fuel-time: 300 behavior: @@ -560,7 +560,7 @@ items#pfence: default:palm_fence: material: nether_brick data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/palm_fence_inventory @@ -632,7 +632,7 @@ items#button: textures: texture: minecraft:block/custom/palm_planks data: - item-name: + item-name: settings: fuel-time: 100 behavior: diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/pebble.yml b/common-files/src/main/resources/resources/default/configuration/blocks/pebble.yml index 6f267d5ad..d9dd1ef1f 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/pebble.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/pebble.yml @@ -2,7 +2,7 @@ items: default:pebble: material: nether_brick data: - item-name: + item-name: model: template: default:model/simplified_generated arguments: diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/reed.yml b/common-files/src/main/resources/resources/default/configuration/blocks/reed.yml index de1e00be9..49ce9b22d 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/reed.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/reed.yml @@ -2,7 +2,7 @@ items: default:reed: material: nether_brick data: - item-name: + item-name: model: template: default:model/simplified_generated arguments: diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/safe_block.yml b/common-files/src/main/resources/resources/default/configuration/blocks/safe_block.yml index ff538a949..103c0a95c 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/safe_block.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/safe_block.yml @@ -2,7 +2,7 @@ items: default:safe_block: material: nether_brick data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/safe_block @@ -31,7 +31,7 @@ items: step: minecraft:block.stone.step behavior: type: simple_storage_block - title: "" + title: "" rows: 1 sounds: open: minecraft:block.iron_trapdoor.open diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/sofa.yml b/common-files/src/main/resources/resources/default/configuration/blocks/sofa.yml index d0b126ea1..bd5e72fd3 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/sofa.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/sofa.yml @@ -2,7 +2,7 @@ items: default:sleeper_sofa: material: nether_brick data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/sleeper_sofa @@ -50,7 +50,7 @@ items: default:sofa: material: nether_brick data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/sofa diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/table_lamp.yml b/common-files/src/main/resources/resources/default/configuration/blocks/table_lamp.yml index 7f7165c56..adb60844a 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/table_lamp.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/table_lamp.yml @@ -2,7 +2,7 @@ items: default:table_lamp: material: nether_brick data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/table_lamp diff --git a/common-files/src/main/resources/resources/default/configuration/blocks/topaz_ore.yml b/common-files/src/main/resources/resources/default/configuration/blocks/topaz_ore.yml index f120a9776..00d5621a5 100644 --- a/common-files/src/main/resources/resources/default/configuration/blocks/topaz_ore.yml +++ b/common-files/src/main/resources/resources/default/configuration/blocks/topaz_ore.yml @@ -2,7 +2,7 @@ items: default:topaz_ore: material: nether_brick data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/topaz_ore @@ -14,7 +14,7 @@ items: default:deepslate_topaz_ore: material: nether_brick data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/deepslate_topaz_ore @@ -31,7 +31,7 @@ items: - '#default:topaz_tools' percent: 0.25 data: - item-name: <#FF8C00> + item-name: <#FF8C00> model: template: default:model/simplified_generated arguments: diff --git a/common-files/src/main/resources/resources/default/configuration/categories.yml b/common-files/src/main/resources/resources/default/configuration/categories.yml index e86e20116..2f9c69cb6 100644 --- a/common-files/src/main/resources/resources/default/configuration/categories.yml +++ b/common-files/src/main/resources/resources/default/configuration/categories.yml @@ -1,16 +1,16 @@ categories: default:default: priority: 1 - name: + name: lore: - - + - icon: default:topaz list: - '#default:palm_tree' - '#default:topaz' - '#default:misc' default:palm_tree: - name: + name: hidden: true icon: default:palm_log list: @@ -30,7 +30,7 @@ categories: - default:palm_pressure_plate - default:palm_button default:topaz: - name: <#FF8C00> + name: <#FF8C00> hidden: true icon: default:topaz list: @@ -51,7 +51,7 @@ categories: - default:topaz_leggings - default:topaz_boots default:misc: - name: + name: hidden: true icon: default:chinese_lantern list: diff --git a/common-files/src/main/resources/resources/default/configuration/emoji.yml b/common-files/src/main/resources/resources/default/configuration/emoji.yml index 4fe4b0e69..aa001996e 100644 --- a/common-files/src/main/resources/resources/default/configuration/emoji.yml +++ b/common-files/src/main/resources/resources/default/configuration/emoji.yml @@ -1,6 +1,6 @@ templates: default:emoji/basic: - content: '> + content: '> emoji: default:emoji_smiley: template: default:emoji/basic diff --git a/common-files/src/main/resources/resources/default/configuration/furniture/bench.yml b/common-files/src/main/resources/resources/default/configuration/furniture/bench.yml index cf5688160..3b4b68471 100644 --- a/common-files/src/main/resources/resources/default/configuration/furniture/bench.yml +++ b/common-files/src/main/resources/resources/default/configuration/furniture/bench.yml @@ -2,7 +2,7 @@ items: default:bench: material: nether_brick data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/bench diff --git a/common-files/src/main/resources/resources/default/configuration/furniture/flower_basket.yml b/common-files/src/main/resources/resources/default/configuration/furniture/flower_basket.yml index 63c508fde..0dd2ac5c2 100644 --- a/common-files/src/main/resources/resources/default/configuration/furniture/flower_basket.yml +++ b/common-files/src/main/resources/resources/default/configuration/furniture/flower_basket.yml @@ -2,7 +2,7 @@ items: default:flower_basket: material: nether_brick data: - item-name: + item-name: model: template: default:model/simplified_generated arguments: diff --git a/common-files/src/main/resources/resources/default/configuration/furniture/wooden_chair.yml b/common-files/src/main/resources/resources/default/configuration/furniture/wooden_chair.yml index 5d62051b1..24471cfb1 100644 --- a/common-files/src/main/resources/resources/default/configuration/furniture/wooden_chair.yml +++ b/common-files/src/main/resources/resources/default/configuration/furniture/wooden_chair.yml @@ -2,7 +2,7 @@ items: default:wooden_chair: material: nether_brick data: - item-name: + item-name: model: type: minecraft:model path: minecraft:item/custom/wooden_chair diff --git a/common-files/src/main/resources/resources/default/configuration/items/cap.yml b/common-files/src/main/resources/resources/default/configuration/items/cap.yml index aaa7a88b3..4f03b1dee 100644 --- a/common-files/src/main/resources/resources/default/configuration/items/cap.yml +++ b/common-files/src/main/resources/resources/default/configuration/items/cap.yml @@ -4,7 +4,7 @@ items: $$<=1.21.1: client-bound-material: leather_horse_armor data: - item-name: + item-name: unbreakable: true remove-components: - attribute_modifiers diff --git a/common-files/src/main/resources/resources/default/configuration/items/flame_elytra.yml b/common-files/src/main/resources/resources/default/configuration/items/flame_elytra.yml index 43425ae92..e89cc0f4e 100644 --- a/common-files/src/main/resources/resources/default/configuration/items/flame_elytra.yml +++ b/common-files/src/main/resources/resources/default/configuration/items/flame_elytra.yml @@ -8,7 +8,7 @@ items: asset-id: flame wings: flame_elytra data: - item-name: <#FF8C00> + item-name: <#FF8C00> model: template: default:model/simplified_elytra arguments: diff --git a/common-files/src/main/resources/resources/default/configuration/items/topaz_armor.yml b/common-files/src/main/resources/resources/default/configuration/items/topaz_armor.yml index fcbaf8c86..8d624a490 100644 --- a/common-files/src/main/resources/resources/default/configuration/items/topaz_armor.yml +++ b/common-files/src/main/resources/resources/default/configuration/items/topaz_armor.yml @@ -2,7 +2,7 @@ templates: default:armor/topaz: material: chainmail_${part} data: - item-name: <#FF8C00> + item-name: <#FF8C00> tooltip-style: minecraft:topaz settings: tags: diff --git a/common-files/src/main/resources/resources/default/configuration/items/topaz_tool_weapon.yml b/common-files/src/main/resources/resources/default/configuration/items/topaz_tool_weapon.yml index 3eb60e3d0..04a893078 100644 --- a/common-files/src/main/resources/resources/default/configuration/items/topaz_tool_weapon.yml +++ b/common-files/src/main/resources/resources/default/configuration/items/topaz_tool_weapon.yml @@ -5,7 +5,7 @@ items: tags: - default:topaz_tools data: - item-name: <#FF8C00> + item-name: <#FF8C00> tooltip-style: minecraft:topaz model: template: default:model/simplified_fishing_rod_2d @@ -18,7 +18,7 @@ items: tags: - default:topaz_tools data: - item-name: <#FF8C00> + item-name: <#FF8C00> tooltip-style: minecraft:topaz model: template: default:model/simplified_bow_2d @@ -33,7 +33,7 @@ items: tags: - default:topaz_tools data: - item-name: <#FF8C00> + item-name: <#FF8C00> tooltip-style: minecraft:topaz model: template: default:model/simplified_crossbow_2d @@ -50,7 +50,7 @@ items: tags: - default:topaz_tools data: - item-name: <#FF8C00> + item-name: <#FF8C00> tooltip-style: minecraft:topaz max-damage: 64 model: @@ -63,7 +63,7 @@ items: tags: - default:topaz_tools data: - item-name: <#FF8C00> + item-name: <#FF8C00> tooltip-style: minecraft:topaz max-damage: 64 model: @@ -76,7 +76,7 @@ items: tags: - default:topaz_tools data: - item-name: <#FF8C00> + item-name: <#FF8C00> tooltip-style: minecraft:topaz max-damage: 64 model: @@ -89,7 +89,7 @@ items: tags: - default:topaz_tools data: - item-name: <#FF8C00> + item-name: <#FF8C00> tooltip-style: minecraft:topaz max-damage: 64 model: @@ -102,7 +102,7 @@ items: tags: - default:topaz_tools data: - item-name: <#FF8C00> + item-name: <#FF8C00> tooltip-style: minecraft:topaz max-damage: 64 model: @@ -122,7 +122,7 @@ items: tags: - default:topaz_tools data: - item-name: <#FF8C00> + item-name: <#FF8C00> tooltip-style: minecraft:topaz max-damage: 300 model: @@ -163,7 +163,7 @@ items: $$1.20.1~1.21.1: bow $$1.21.2~1.21.3: honey_bottle data: - item-name: <#FF8C00> + item-name: <#FF8C00> components: minecraft:max_damage: 300 $$>=1.21.2: From 0832e1648188cc225c4a3f1a72c6f0ac299666df Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Sun, 9 Nov 2025 15:28:55 +0800 Subject: [PATCH 37/37] =?UTF-8?q?=E6=B7=BB=E5=8A=A0wiki=E5=AD=90=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitmodules | 3 +++ wiki | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 wiki diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..b406eaf71 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "wiki"] + path = wiki + url = https://github.com/Xiao-MoMi/craft-engine-wiki.git diff --git a/wiki b/wiki new file mode 160000 index 000000000..bec8bb7cf --- /dev/null +++ b/wiki @@ -0,0 +1 @@ +Subproject commit bec8bb7cf8c4331dd54bdc4bb27edfa664805e66