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