diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitPlatform.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitPlatform.java index 1d43f760f..798b1ea17 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitPlatform.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitPlatform.java @@ -1,11 +1,14 @@ package net.momirealms.craftengine.bukkit.plugin; +import com.google.gson.JsonElement; import com.mojang.brigadier.exceptions.CommandSyntaxException; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistryOps; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.Platform; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; +import net.momirealms.sparrow.nbt.CompoundTag; +import net.momirealms.sparrow.nbt.Tag; import org.bukkit.Bukkit; import java.util.Map; @@ -19,14 +22,36 @@ public class BukkitPlatform implements Platform { @SuppressWarnings("unchecked") @Override - public Object nbt2Java(String nbt) { + public Object snbtToJava(String nbt) { try { Object tag = FastNMS.INSTANCE.method$TagParser$parseCompoundFully("{\"root\":" + nbt + "}"); Map map = (Map) MRegistryOps.NBT.convertTo(MRegistryOps.JAVA, tag); return map.get("root"); } catch (CommandSyntaxException e) { CraftEngine.instance().debug(e::getMessage); - throw new LocalizedResourceConfigException("warning.config.template.argument.default_value.invalid_syntax", e, nbt); + throw new LocalizedResourceConfigException("warning.config.type.snbt.invalid_syntax", e, nbt); } } + + @Override + public Tag jsonToSparrowNBT(JsonElement json) { + return MRegistryOps.JSON.convertTo(MRegistryOps.SPARROW_NBT, json); + } + + @Override + public Tag snbtToSparrowNBT(String nbt) { + try { + Object tag = FastNMS.INSTANCE.method$TagParser$parseCompoundFully("{\"root\":" + nbt + "}"); + CompoundTag map = (CompoundTag) MRegistryOps.NBT.convertTo(MRegistryOps.SPARROW_NBT, tag); + return map.get("root"); + } catch (CommandSyntaxException e) { + CraftEngine.instance().debug(e::getMessage); + throw new LocalizedResourceConfigException("warning.config.type.snbt.invalid_syntax", e, nbt); + } + } + + @Override + public Tag javaToSparrowNBT(Object object) { + return MRegistryOps.JAVA.convertTo(MRegistryOps.SPARROW_NBT, object); + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MRegistryOps.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MRegistryOps.java index da5b892ab..dd90cb582 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MRegistryOps.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MRegistryOps.java @@ -42,7 +42,7 @@ public final class MRegistryOps { // 1.20.1-1.20.4 JAVA = (DynamicOps) CoreReflections.method$RegistryOps$create.invoke(null, LegacyJavaOps.INSTANCE, FastNMS.INSTANCE.registryAccess()); } else { - JAVA = null; + throw new ReflectionInitException("Could not find JavaOps"); } NBT = (DynamicOps) CoreReflections.method$RegistryOps$create.invoke(null, ReflectionUtils.getDeclaredField(clazz$NbtOps, clazz$NbtOps, 0).get(null), FastNMS.INSTANCE.registryAccess()); JSON = (DynamicOps) CoreReflections.method$RegistryOps$create.invoke(null, JsonOps.INSTANCE, FastNMS.INSTANCE.registryAccess()); diff --git a/common-files/src/main/resources/translations/en.yml b/common-files/src/main/resources/translations/en.yml index 5612c8ae3..9aee26b3c 100644 --- a/common-files/src/main/resources/translations/en.yml +++ b/common-files/src/main/resources/translations/en.yml @@ -71,6 +71,7 @@ warning.config.type.float: "Issue found in file - Failed to load warning.config.type.double: "Issue found in file - Failed to load '': Cannot cast '' to double type for option ''." warning.config.type.quaternionf: "Issue found in file - Failed to load '': Cannot cast '' to Quaternionf type for option ''." warning.config.type.vector3f: "Issue found in file - Failed to load '': Cannot cast '' to Vector3f type for option ''." +warning.config.type.snbt.invalid_syntax: "Issue found in file - Failed to load '': Invalid snbt syntax ''." warning.config.number.missing_type: "Issue found in file - The config '' is missing the required 'type' argument for number argument." warning.config.number.invalid_type: "Issue found in file - The config '' is using an invalid number argument type ''." warning.config.number.missing_argument: "Issue found in file - The config '' is missing the argument for 'number'." @@ -137,7 +138,6 @@ warning.config.template.duplicate: "Issue found in file - Duplic warning.config.template.invalid: "Issue found in file - The config '' is using an invalid template ''." warning.config.template.argument.self_increase_int.invalid_range: "Issue found in file - The template '' is using a 'from' '' larger than 'to' '' in 'self_increase_int' argument." warning.config.template.argument.list.invalid_type: "Issue found in file - The template '' is using a 'list' argument which expects a 'List' as argument while the input argument is a(n) ''." -warning.config.template.argument.default_value.invalid_syntax: "Issue found in file - The template '' is using an invalid default value '' for argument ''." warning.config.vanilla_loot.missing_type: "Issue found in file - The vanilla loot '' is missing the required 'type' argument." warning.config.vanilla_loot.invalid_type: "Issue found in file - The vanilla loot '' is using an invalid type ''. Allowed types: []." warning.config.vanilla_loot.block.invalid_target: "Issue found in file - Invalid block target '' in vanilla loot ''." diff --git a/common-files/src/main/resources/translations/zh_cn.yml b/common-files/src/main/resources/translations/zh_cn.yml index 522ec704f..4e993c957 100644 --- a/common-files/src/main/resources/translations/zh_cn.yml +++ b/common-files/src/main/resources/translations/zh_cn.yml @@ -71,6 +71,7 @@ warning.config.type.boolean: "在文件 发现问题 - 无法加 warning.config.type.double: "在文件 发现问题 - 无法加载 '': 无法将 '' 转换为双精度类型 (选项 '')" warning.config.type.quaternionf: "在文件 发现问题 - 无法加载 '': 无法将 '' 转换为四元数类型 (选项 '')" warning.config.type.vector3f: "在文件 发现问题 - 无法加载 '': 无法将 '' 转换为三维向量类型 (选项 '')" +warning.config.type.snbt.invalid_syntax: "在文件 发现问题 - 无法加载 '': 无效的 SNBT 语法 ''." warning.config.number.missing_type: "在文件 发现问题 - 配置项 '' 缺少数字类型所需的 'type' 参数" warning.config.number.invalid_type: "在文件 发现问题 - 配置项 '' 使用了无效的数字类型 ''" warning.config.number.missing_argument: "在文件 发现问题 - 配置项 '' 缺少数字参数" @@ -137,7 +138,6 @@ warning.config.template.duplicate: "在文件 发现问题 - 重 warning.config.template.argument.self_increase_int.invalid_range: "在文件 发现问题 - 模板 '' 在 'self_increase_int' 参数中使用了一个起始值 '' 大于终止值 ''" warning.config.template.invalid: "在文件 发现问题 - 配置 '' 使用了无效的模板 ''." warning.config.template.argument.list.invalid_type: "在文件 发现问题 - 模板 '' 的 'list' 参数需要列表类型 但输入参数类型为 ''" -warning.config.template.argument.default_value.invalid_syntax: "在文件 发现问题 - 模板 '' 在参数 '' 中使用了无效的默认值 ''." warning.config.vanilla_loot.missing_type: "在文件 发现问题 - 原版战利品 '' 缺少必需的 'type' 参数" warning.config.vanilla_loot.invalid_type: "在文件 发现问题 - 原版战利品 '' 使用了无效类型 '' 允许的类型: []" warning.config.vanilla_loot.block.invalid_target: "在文件 发现问题 - 原版战利品 '' 中存在无效的方块目标 ''" diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ComponentModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ComponentModifier.java index 5fb24fa13..2406e10eb 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ComponentModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ComponentModifier.java @@ -6,6 +6,7 @@ import net.momirealms.craftengine.core.item.ComponentKeys; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemBuildContext; import net.momirealms.craftengine.core.item.NetworkItemHandler; +import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.util.GsonHelper; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.Pair; @@ -17,15 +18,15 @@ import java.util.List; import java.util.Map; public class ComponentModifier implements ItemDataModifier { - private final List> arguments; - private JsonObject customData = null; + private final List> arguments; + private CompoundTag customData = null; public ComponentModifier(Map arguments) { - List> pairs = new ArrayList<>(arguments.size()); + List> pairs = new ArrayList<>(arguments.size()); for (Map.Entry entry : arguments.entrySet()) { Key key = Key.of(entry.getKey()); if (key.equals(ComponentKeys.CUSTOM_DATA)) { - this.customData = parseJsonObjectValue(entry.getValue()); + this.customData = (CompoundTag) parseValue(entry.getValue()); } else { pairs.add(new Pair<>(key, parseValue(entry.getValue()))); } @@ -33,28 +34,19 @@ public class ComponentModifier implements ItemDataModifier { this.arguments = pairs; } - public List> arguments() { + public List> arguments() { return arguments; } - private Object parseValue(Object value) { + private Tag parseValue(Object value) { if (value instanceof String string) { if (string.startsWith("(json) ")) { - return GsonHelper.get().fromJson(string.substring("(json) ".length()), JsonElement.class); + return CraftEngine.instance().platform().jsonToSparrowNBT(GsonHelper.get().fromJson(string.substring("(json) ".length()), JsonElement.class)); + } else if (string.startsWith("(snbt) ")) { + return CraftEngine.instance().platform().snbtToSparrowNBT(string.substring("(snbt) ".length())); } } - return value; - } - - private JsonObject parseJsonObjectValue(Object value) { - if (value instanceof String string) { - if (string.startsWith("(json) ")) { - return GsonHelper.get().fromJson(string.substring("(json) ".length()), JsonObject.class); - } - } else if (value instanceof Map map) { - return (JsonObject) GsonHelper.get().toJsonTree(map, Map.class); - } - throw new UnsupportedOperationException("Invalid minecraft:custom_data value: " + value.toString()); + return CraftEngine.instance().platform().javaToSparrowNBT(value); } @Override @@ -64,13 +56,16 @@ public class ComponentModifier implements ItemDataModifier { @Override public Item apply(Item item, ItemBuildContext context) { - for (Pair entry : this.arguments) { - item.setComponent(entry.left(), entry.right()); + for (Pair entry : this.arguments) { + item.setNBTComponent(entry.left(), entry.right()); } if (this.customData != null) { - JsonObject tag = (JsonObject) item.getJsonComponent(ComponentKeys.CUSTOM_DATA); + CompoundTag tag = (CompoundTag) item.getNBTTag(ComponentKeys.CUSTOM_DATA); if (tag != null) { - item.setComponent(ComponentKeys.CUSTOM_DATA, GsonHelper.shallowMerge(this.customData, tag)); + for (Map.Entry entry : this.customData.entrySet()) { + tag.put(entry.getKey(), entry.getValue()); + } + item.setComponent(ComponentKeys.CUSTOM_DATA, tag); } else { item.setComponent(ComponentKeys.CUSTOM_DATA, this.customData); } @@ -80,7 +75,7 @@ public class ComponentModifier implements ItemDataModifier { @Override public Item prepareNetworkItem(Item item, ItemBuildContext context, CompoundTag networkData) { - for (Pair entry : this.arguments) { + for (Pair entry : this.arguments) { Tag previous = item.getNBTComponent(entry.left()); if (previous != null) { networkData.put(entry.left().asString(), NetworkItemHandler.pack(NetworkItemHandler.Operation.ADD, previous)); diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/Platform.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/Platform.java index 09b32b9a5..03e0c52b2 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/Platform.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/Platform.java @@ -1,8 +1,17 @@ package net.momirealms.craftengine.core.plugin; +import com.google.gson.JsonElement; +import net.momirealms.sparrow.nbt.Tag; + public interface Platform { void dispatchCommand(String command); - Object nbt2Java(String nbt); + Object snbtToJava(String nbt); + + Tag jsonToSparrowNBT(JsonElement json); + + Tag snbtToSparrowNBT(String nbt); + + Tag javaToSparrowNBT(Object object); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManager.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManager.java index 4d6419008..2f6fb429a 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManager.java @@ -76,7 +76,7 @@ public interface TemplateManager extends Manageable { this.placeholder = placeholderContent.substring(0, separatorIndex); String defaultValueString = placeholderContent.substring(separatorIndex + 2); try { - this.defaultValue = CraftEngine.instance().platform().nbt2Java(defaultValueString); + this.defaultValue = CraftEngine.instance().platform().snbtToJava(defaultValueString); } catch (LocalizedResourceConfigException e) { e.appendTailArgument(this.placeholder); throw e;