From ef1caaa05afa367acd6de3d2f76ac5af3d591108 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Fri, 9 May 2025 02:05:02 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E6=B7=BB=E5=8A=A0special=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E7=94=9F=E6=88=90=EF=BC=8C=E5=AE=8C=E5=96=84special?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/translations/en.yml | 3 ++- .../src/main/resources/translations/tr.yml | 1 - .../src/main/resources/translations/zh_cn.yml | 3 ++- .../item/factory/BukkitItemFactory.java | 2 +- .../core/pack/model/SpecialItemModel.java | 26 ++++++++++++++++--- .../pack/model/special/ChestSpecialModel.java | 4 ++- .../pack/model/special/HeadSpecialModel.java | 11 +++++--- .../model/special/ShulkerBoxSpecialModel.java | 11 +++++--- gradle.properties | 2 +- 9 files changed, 47 insertions(+), 16 deletions(-) diff --git a/bukkit/loader/src/main/resources/translations/en.yml b/bukkit/loader/src/main/resources/translations/en.yml index ff18b0826..d7240fa55 100644 --- a/bukkit/loader/src/main/resources/translations/en.yml +++ b/bukkit/loader/src/main/resources/translations/en.yml @@ -179,6 +179,8 @@ warning.config.item.model.select.case.missing_model: "Issue found in fil warning.config.item.model.select.block_state.missing_property: "Issue found in file - The item '' is missing the required 'block-state-property' argument for property 'minecraft:block_state'." warning.config.item.model.select.local_time.missing_pattern: "Issue found in file - The item '' is missing the required 'pattern' argument for property 'minecraft:local_time'." warning.config.item.model.special.missing_type: "Issue found in file - The item '' is missing the required 'type' argument for model 'minecraft:special'." +warning.config.item.model.special.missing_path: "Issue found in file - The item '' is missing the required 'path' argument for model 'minecraft:special'." +warning.config.item.model.special.invalid_path: "Issue found in file - The item '' has an invalid 'path' argument '' for model 'minecraft:special' which contains illegal characters. Please read https://minecraft.wiki/w/Resource_location#Legal_characters." warning.config.item.model.special.invalid_type: "Issue found in file - The item '' is using an invalid type '' for model 'minecraft:special'." warning.config.item.model.special.banner.missing_color: "Issue found in file - The item '' is missing the required 'color' argument for special model 'minecraft:banner'." warning.config.item.model.special.bed.missing_texture: "Issue found in file - The item '' is missing the required 'texture' argument for special model 'minecraft:bed'." @@ -189,7 +191,6 @@ warning.config.item.model.special.chest.invalid_openness: "Issue found i warning.config.item.model.special.shulker_box.missing_texture: "Issue found in file - The item '' is missing the required 'texture' argument for special model 'minecraft:shulker_box'." warning.config.item.model.special.shulker_box.invalid_openness: "Issue found in file - The item '' is using an invalid 'openness' value '' for special model 'minecraft:shulker_box'. Valid range '0~1.'" warning.config.item.model.special.head.missing_kind: "Issue found in file - The item '' is missing the required 'kind' argument for special model 'minecraft:head'." -warning.config.item.model.special.head.missing_texture: "Issue found in file - The item '' is missing the required 'texture' argument for special model 'minecraft:head'." warning.config.block.duplicate: "Issue found in file - Duplicated block ''. Please check if there is the same configuration in other files." warning.config.block.missing_state: "Issue found in file - The block '' is missing the required 'state' argument." warning.config.block.state.property.missing_type: "Issue found in file - The block '' is missing the required 'type' argument for property ''." diff --git a/bukkit/loader/src/main/resources/translations/tr.yml b/bukkit/loader/src/main/resources/translations/tr.yml index def783519..7c1c475b5 100644 --- a/bukkit/loader/src/main/resources/translations/tr.yml +++ b/bukkit/loader/src/main/resources/translations/tr.yml @@ -167,7 +167,6 @@ warning.config.item.model.special.chest.invalid_openness: " dosya warning.config.item.model.special.shulker_box.missing_texture: " dosyasında sorun bulundu - '' eşyası, 'minecraft:shulker_box' özel modeli için gerekli 'texture' argümanı eksik." warning.config.item.model.special.shulker_box.invalid_openness: " dosyasında sorun bulundu - '' eşyası, 'minecraft:shulker_box' özel modeli için geçersiz bir 'openness' değeri '' kullanıyor. Geçerli aralık '0~1.'" warning.config.item.model.special.head.missing_kind: " dosyasında sorun bulundu - '' eşyası, 'minecraft:head' özel modeli için gerekli 'kind' argümanı eksik." -warning.config.item.model.special.head.missing_texture: " dosyasında sorun bulundu - '' eşyası, 'minecraft:head' özel modeli için gerekli 'texture' argümanı eksik." warning.config.block.duplicate: " dosyasında sorun bulundu - Yinelenen blok ''. Diğer dosyalarda aynı yapılandırmanın olup olmadığını kontrol edin." warning.config.block.missing_state: " dosyasında sorun bulundu - '' bloğu gerekli 'state' argümanı eksik." warning.config.block.state.property.missing_type: " dosyasında sorun bulundu - '' bloğu, '' özelliği için gerekli 'type' argümanı eksik." diff --git a/bukkit/loader/src/main/resources/translations/zh_cn.yml b/bukkit/loader/src/main/resources/translations/zh_cn.yml index d2e6ed5f9..2429e0ff3 100644 --- a/bukkit/loader/src/main/resources/translations/zh_cn.yml +++ b/bukkit/loader/src/main/resources/translations/zh_cn.yml @@ -179,6 +179,8 @@ warning.config.item.model.select.case.missing_model: "在文件 warning.config.item.model.select.block_state.missing_property: "在文件 发现问题 - 物品 '' 的 'minecraft:block_state' 属性缺少必需的 'block-state-property' 参数" warning.config.item.model.select.local_time.missing_pattern: "在文件 发现问题 - 物品 '' 的 'minecraft:local_time' 属性缺少必需的 'pattern' 参数" warning.config.item.model.special.missing_type: "在文件 发现问题 - 物品 '' 的 'minecraft:special' 模型缺少必需的 'type' 参数" +warning.config.item.model.special.missing_path: "在文件 发现问题 - 物品 '' 的 'minecraft:special' 模型缺少必需的模型 'path' 参数" +warning.config.item.model.special.invalid_path: "在文件 发现问题 - 物品 '' 的 'minecraft:special' 模型路径 '' 包含非法字符 请参考 https://zh.minecraft.wiki/w/%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4ID#%E5%90%88%E6%B3%95%E5%AD%97%E7%AC%A6" warning.config.item.model.special.invalid_type: "在文件 发现问题 - 物品 '' 的 'minecraft:special' 模型使用了无效类型 ''" warning.config.item.model.special.banner.missing_color: "在文件 发现问题 - 物品 '' 的 'minecraft:banner' 特殊模型缺少必需的 'color' 参数" warning.config.item.model.special.bed.missing_texture: "在文件 发现问题 - 物品 '' 的 'minecraft:bed' 特殊模型缺少必需的 'texture' 参数" @@ -189,7 +191,6 @@ warning.config.item.model.special.chest.invalid_openness: "在文件 在文件 发现问题 - 物品 '' 的 'minecraft:shulker_box' 特殊模型缺少必需的 'texture' 参数" warning.config.item.model.special.shulker_box.invalid_openness: "在文件 发现问题 - 物品 '' 的 'minecraft:shulker_box' 特殊模型使用了无效的 'openness' 值 '' 有效范围应为 0~1" warning.config.item.model.special.head.missing_kind: "在文件 发现问题 - 物品 '' 的 'minecraft:head' 特殊模型缺少必需的 'kind' 参数" -warning.config.item.model.special.head.missing_texture: "在文件 发现问题 - 物品 '' 的 'minecraft:head' 特殊模型缺少必需的 'texture' 参数" warning.config.block.duplicate: "在文件 发现问题 - 重复的方块 '' 请检查其他文件中是否存在相同配置" warning.config.block.missing_state: "在文件 发现问题 - 方块 '' 缺少必需的 'state' 参数" warning.config.block.state.property.missing_type: "在文件 发现问题 - 方块 '' 的属性 '' 缺少必需的 'type' 参数" diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java index 149f335f5..853271e93 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java @@ -39,7 +39,7 @@ public abstract class BukkitItemFactory> extend case "1.21.4" -> { return new ComponentItemFactory1_21_4(plugin); } - case "1.21.5", "1.22", "1.22.1" -> { + case "1.21.5", "1.21.6", "1.22", "1.22.1" -> { return new ComponentItemFactory1_21_5(plugin); } default -> throw new IllegalStateException("Unsupported server version: " + plugin.serverVersion()); diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/SpecialItemModel.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/SpecialItemModel.java index 99f125240..ccfa2e026 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/SpecialItemModel.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/SpecialItemModel.java @@ -1,11 +1,15 @@ package net.momirealms.craftengine.core.pack.model; import com.google.gson.JsonObject; +import net.momirealms.craftengine.core.pack.ResourceLocation; import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration; import net.momirealms.craftengine.core.pack.model.special.SpecialModel; import net.momirealms.craftengine.core.pack.model.special.SpecialModels; +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 org.jetbrains.annotations.Nullable; import java.util.List; import java.util.Map; @@ -15,10 +19,12 @@ public class SpecialItemModel implements ItemModel { public static final Factory FACTORY = new Factory(); private final SpecialModel specialModel; private final String base; + private final ModelGeneration modelGeneration; - public SpecialItemModel(SpecialModel specialModel, String base) { + public SpecialItemModel(SpecialModel specialModel, String base, @Nullable ModelGeneration generation) { this.specialModel = specialModel; this.base = base; + this.modelGeneration = generation; } public SpecialModel specialModel() { @@ -45,16 +51,28 @@ public class SpecialItemModel implements ItemModel { @Override public List modelsToGenerate() { - return List.of(); + if (this.modelGeneration == null) { + return List.of(); + } else { + return List.of(this.modelGeneration); + } } public static class Factory implements ItemModelFactory { @Override public ItemModel create(Map arguments) { - String base = Objects.requireNonNull(arguments.get("base")).toString(); + String base = ResourceConfigUtils.requireNonEmptyStringOrThrow(ResourceConfigUtils.get(arguments, "base", "path"), "warning.config.item.model.special.missing_path"); + if (!ResourceLocation.isValid(base)) { + throw new LocalizedResourceConfigException("warning.config.item.model.special.invalid_path", base); + } + Map generation = MiscUtils.castToMap(arguments.get("generation"), true); + ModelGeneration modelGeneration = null; + if (generation != null) { + modelGeneration = new ModelGeneration(Key.of(base), generation); + } Map model = MiscUtils.castToMap(arguments.get("model"), false); - return new SpecialItemModel(SpecialModels.fromMap(model), base); + return new SpecialItemModel(SpecialModels.fromMap(model), base, modelGeneration); } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/special/ChestSpecialModel.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/special/ChestSpecialModel.java index 31aaf4563..a4cdce121 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/special/ChestSpecialModel.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/special/ChestSpecialModel.java @@ -27,7 +27,9 @@ public class ChestSpecialModel implements SpecialModel { JsonObject json = new JsonObject(); json.addProperty("type", type().toString()); json.addProperty("texture", texture); - json.addProperty("openness", openness); + if (openness > 0) { + json.addProperty("openness", openness); + } return json; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/special/HeadSpecialModel.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/special/HeadSpecialModel.java index 6f1cf530c..7ee58315d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/special/HeadSpecialModel.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/special/HeadSpecialModel.java @@ -5,6 +5,7 @@ import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.ResourceConfigUtils; import java.util.Map; +import java.util.Optional; public class HeadSpecialModel implements SpecialModel { public static final Factory FACTORY = new Factory(); @@ -28,8 +29,12 @@ public class HeadSpecialModel implements SpecialModel { JsonObject json = new JsonObject(); json.addProperty("type", type().toString()); json.addProperty("kind", kind); - json.addProperty("texture", texture); - json.addProperty("animation", animation); + if (texture != null) { + json.addProperty("texture", texture); + } + if (animation != 0) { + json.addProperty("animation", animation); + } return json; } @@ -38,7 +43,7 @@ public class HeadSpecialModel implements SpecialModel { @Override public SpecialModel create(Map arguments) { String kind = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("kind"), "warning.config.item.model.special.head.missing_kind"); - String texture = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("texture"), "warning.config.item.model.special.head.missing_texture"); + String texture = Optional.ofNullable(arguments.get("texture")).map(String::valueOf).orElse(null); int animation = ResourceConfigUtils.getAsInt(arguments.getOrDefault("animation", 0), "animation"); return new HeadSpecialModel(kind, texture, animation); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/special/ShulkerBoxSpecialModel.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/special/ShulkerBoxSpecialModel.java index 0eaf640a6..2ba8f374c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/special/ShulkerBoxSpecialModel.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/special/ShulkerBoxSpecialModel.java @@ -5,9 +5,12 @@ import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigExce import net.momirealms.craftengine.core.util.Direction; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import org.jetbrains.annotations.Nullable; +import java.awt.desktop.OpenFilesEvent; import java.util.Locale; import java.util.Map; +import java.util.Optional; public class ShulkerBoxSpecialModel implements SpecialModel { public static final Factory FACTORY = new Factory(); @@ -15,7 +18,7 @@ public class ShulkerBoxSpecialModel implements SpecialModel { private final float openness; private final Direction orientation; - public ShulkerBoxSpecialModel(String texture, float openness, Direction orientation) { + public ShulkerBoxSpecialModel(String texture, float openness, @Nullable Direction orientation) { this.texture = texture; this.openness = openness; this.orientation = orientation; @@ -31,8 +34,10 @@ public class ShulkerBoxSpecialModel implements SpecialModel { JsonObject json = new JsonObject(); json.addProperty("type", type().toString()); json.addProperty("texture", texture); + if (orientation != null) { + json.addProperty("orientation", orientation.name().toLowerCase(Locale.ENGLISH)); + } json.addProperty("openness", openness); - json.addProperty("orientation", orientation.name().toLowerCase(Locale.ENGLISH)); return json; } @@ -42,7 +47,7 @@ public class ShulkerBoxSpecialModel implements SpecialModel { public SpecialModel create(Map arguments) { float openness = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("openness", 0), "openness"); String texture = ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("texture"), "warning.config.item.model.special.shulker_box.missing_texture"); - Direction orientation = Direction.valueOf(arguments.getOrDefault("orientation", "down").toString().toUpperCase(Locale.ENGLISH)); + Direction orientation = Optional.ofNullable(arguments.get("orientation")).map(String::valueOf).map(String::toUpperCase).map(Direction::valueOf).orElse(null); if (openness > 1 || openness < 0) { throw new LocalizedResourceConfigException("warning.config.item.model.special.shulker_box.invalid_openness", String.valueOf(openness)); } diff --git a/gradle.properties b/gradle.properties index 978455b6b..c7950e2ef 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.53.2 +project_version=0.0.53.3 config_version=32 lang_version=12 project_group=net.momirealms From 81cf2055e40394dea1bf76b59bdd1c26fdd74aa7 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Fri, 9 May 2025 02:34:23 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E4=B8=BA=E5=AE=B6=E5=85=B7=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E8=87=AA=E5=AE=9A=E4=B9=89=E6=8E=89=E8=90=BD=E7=89=A9?= =?UTF-8?q?=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/default/configuration/furniture.yml | 3 +++ .../bukkit/api/CraftEngineFurniture.java | 2 +- .../entity/furniture/BukkitFurnitureManager.java | 8 ++++++-- .../bukkit/entity/furniture/LoadedFurniture.java | 15 +++++++++++++-- .../core/entity/furniture/CustomFurniture.java | 4 +++- 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/bukkit/loader/src/main/resources/resources/default/configuration/furniture.yml b/bukkit/loader/src/main/resources/resources/default/configuration/furniture.yml index 05578bdbc..e8eb30a91 100644 --- a/bukkit/loader/src/main/resources/resources/default/configuration/furniture.yml +++ b/bukkit/loader/src/main/resources/resources/default/configuration/furniture.yml @@ -17,6 +17,7 @@ items: place: minecraft:block.bamboo_wood.place placement: ground: + loot-spawn-offset: 0.5,0.5,0 rules: # ANY / FOUR / EIGHT / SIXTEEN / NORTH / EAST / WEST / SOUTH rotation: FOUR @@ -61,6 +62,7 @@ items: place: minecraft:block.lantern.place placement: ground: + loot-spawn-offset: 0,0.2,0 rules: rotation: ANY alignment: QUARTER @@ -111,6 +113,7 @@ items: place: minecraft:block.bamboo_wood.place placement: ground: + loot-spawn-offset: 0,0.4,0 rules: rotation: ANY alignment: ANY diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineFurniture.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineFurniture.java index 134fda9a6..d611eec59 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineFurniture.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineFurniture.java @@ -263,7 +263,7 @@ public final class CraftEngineFurniture { @Nullable net.momirealms.craftengine.core.entity.player.Player player, boolean dropLoot, boolean playSound) { - Location location = loadedFurniture.location(); + Location location = loadedFurniture.dropLocation(); loadedFurniture.destroy(); LootTable lootTable = (LootTable) loadedFurniture.config().lootTable(); Vec3d vec3d = LocationUtils.toVec3d(location); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java index faad973b1..120430faa 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java @@ -124,6 +124,8 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager { AnchorType anchorType = AnchorType.valueOf(entry.getKey().toUpperCase(Locale.ENGLISH)); Map placementArguments = MiscUtils.castToMap(entry.getValue(), true); + Optional optionalLootSpawnOffset = Optional.ofNullable(placementArguments.get("loot-spawn-offset")).map(it -> MiscUtils.getAsVector3f(it, "loot-spawn-offset")); + // furniture display elements List elements = new ArrayList<>(); List> elementConfigs = (List>) placementArguments.getOrDefault("elements", List.of()); @@ -178,7 +180,8 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager { hitboxes.toArray(new HitBox[0]), rotationRule, alignmentRule, - externalModel + externalModel, + optionalLootSpawnOffset )); } else { placements.put(anchorType, new CustomFurniture.Placement( @@ -186,7 +189,8 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager { hitboxes.toArray(new HitBox[0]), RotationRule.ANY, AlignmentRule.CENTER, - externalModel + externalModel, + optionalLootSpawnOffset )); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java index 40505ab8d..ac8ba908a 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java @@ -75,9 +75,9 @@ public class LoadedFurniture implements Furniture { } catch (Exception e) { CraftEngine.instance().logger().warn("Failed to load external model for furniture " + id, e); } - hasExternalModel = true; + this.hasExternalModel = true; } else { - hasExternalModel = false; + this.hasExternalModel = false; } float yaw = this.location.getYaw(); @@ -176,6 +176,17 @@ public class LoadedFurniture implements Furniture { return baseEntity().isValid(); } + @NotNull + public Location dropLocation() { + Optional dropOffset = config().getPlacement(this.anchorType).dropOffset(); + if (dropOffset.isEmpty()) { + return location(); + } + Quaternionf conjugated = QuaternionUtils.toQuaternionf(0, Math.toRadians(180 - this.location.getYaw()), 0).conjugate(); + Vector3f offset = conjugated.transform(new Vector3f(dropOffset.get())); + return new Location(this.location.getWorld(), this.location.getX() + offset.x, this.location.getY() + offset.y, this.location.getZ() - offset.z); + } + @Override public void destroy() { if (!isValid()) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/CustomFurniture.java b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/CustomFurniture.java index 1b8679ae6..cbf5f12c9 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/CustomFurniture.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/CustomFurniture.java @@ -4,6 +4,7 @@ import net.momirealms.craftengine.core.loot.LootTable; import net.momirealms.craftengine.core.util.Key; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.joml.Vector3f; import java.util.EnumMap; import java.util.Optional; @@ -60,6 +61,7 @@ public class CustomFurniture { HitBox[] hitBoxes, RotationRule rotationRule, AlignmentRule alignmentRule, - Optional externalModel) { + Optional externalModel, + Optional dropOffset) { } } From d6a081706932c34938b60c62a1541645563cc7b7 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Fri, 9 May 2025 03:07:13 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E5=92=8Crel=E5=8F=98=E9=87=8F=E8=A7=A3?= =?UTF-8?q?=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BukkitCompatibilityManager.java | 5 ++ .../papi/PlaceholderAPIUtils.java | 5 ++ .../advancement/BukkitAdvancementManager.java | 6 +- .../bukkit/block/BukkitBlockManager.java | 6 +- .../furniture/BukkitFurnitureManager.java | 6 +- .../bukkit/item/BukkitItemManager.java | 6 +- .../bukkit/loot/BukkitVanillaLootManager.java | 6 +- .../core/advancement/AdvancementManager.java | 4 +- .../craftengine/core/block/BlockManager.java | 4 +- .../entity/furniture/FurnitureManager.java | 4 +- .../core/font/AbstractFontManager.java | 10 ++-- .../craftengine/core/font/FontManager.java | 4 +- .../craftengine/core/item/ItemManager.java | 4 +- .../item/recipe/AbstractRecipeManager.java | 6 +- .../core/item/recipe/RecipeManager.java | 4 +- .../core/loot/VanillaLootManager.java | 4 +- .../core/pack/AbstractPackManager.java | 18 +++--- .../core/pack/LoadingSequence.java | 27 ++++----- .../craftengine/core/pack/PackManager.java | 10 ++-- .../core/plugin/CompatibilityManager.java | 2 + .../craftengine/core/plugin/CraftEngine.java | 12 ++++ .../craftengine/core/plugin/Plugin.java | 3 + ...igSectionParser.java => ConfigParser.java} | 13 +++-- .../config/template/TemplateManager.java | 9 +-- .../config/template/TemplateManagerImpl.java | 23 +++----- .../plugin/context/AbstractCommonContext.java | 2 +- .../plugin/context/GlobalVariableManager.java | 57 +++++++++++++++++++ .../plugin/context/PlayerOptionalContext.java | 7 ++- .../core/plugin/context/ViewerContext.java | 16 ++++-- .../gui/category/ItemBrowserManager.java | 4 +- .../gui/category/ItemBrowserManagerImpl.java | 6 +- .../plugin/locale/TranslationManager.java | 4 +- .../plugin/locale/TranslationManagerImpl.java | 10 ++-- .../text/minimessage/GlobalVariableTag.java | 38 +++++++++++++ .../minimessage/RelationalPlaceholderTag.java | 40 +++++++++++++ .../core/sound/AbstractSoundManager.java | 10 ++-- .../craftengine/core/sound/SoundManager.java | 4 +- 37 files changed, 285 insertions(+), 114 deletions(-) rename core/src/main/java/net/momirealms/craftengine/core/plugin/config/{ConfigSectionParser.java => ConfigParser.java} (52%) create mode 100644 core/src/main/java/net/momirealms/craftengine/core/plugin/context/GlobalVariableManager.java create mode 100644 core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/GlobalVariableTag.java create mode 100644 core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/RelationalPlaceholderTag.java diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java index 4de975ecd..c4888be8c 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java @@ -192,6 +192,11 @@ public class BukkitCompatibilityManager implements CompatibilityManager { return PlaceholderAPIUtils.parse((org.bukkit.entity.Player) player.platformPlayer(), text); } + @Override + public String parse(Player player1, Player player2, String text) { + return PlaceholderAPIUtils.parse((org.bukkit.entity.Player) player1.platformPlayer(), (org.bukkit.entity.Player) player2.platformPlayer(), text); + } + @Override public int getPlayerProtocolVersion(UUID uuid) { return ViaVersionUtils.getPlayerProtocolVersion(uuid); diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/papi/PlaceholderAPIUtils.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/papi/PlaceholderAPIUtils.java index 824236dda..e96cb46dc 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/papi/PlaceholderAPIUtils.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/papi/PlaceholderAPIUtils.java @@ -3,6 +3,7 @@ package net.momirealms.craftengine.bukkit.compatibility.papi; import me.clip.placeholderapi.PlaceholderAPI; import net.momirealms.craftengine.core.plugin.CraftEngine; import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; public class PlaceholderAPIUtils { @@ -12,6 +13,10 @@ public class PlaceholderAPIUtils { return PlaceholderAPI.setPlaceholders(player, text); } + public static String parse(Player player1, Player player2, String text) { + return PlaceholderAPI.setRelationalPlaceholders(player1, player2, text); + } + public static void registerExpansions(CraftEngine plugin) { new ImageExpansion(plugin).register(); new ShiftExpansion(plugin).register(); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/advancement/BukkitAdvancementManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/advancement/BukkitAdvancementManager.java index 74e2a5916..8df8c971d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/advancement/BukkitAdvancementManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/advancement/BukkitAdvancementManager.java @@ -6,7 +6,7 @@ import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.core.advancement.AbstractAdvancementManager; import net.momirealms.craftengine.core.pack.LoadingSequence; import net.momirealms.craftengine.core.pack.Pack; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.GsonHelper; import net.momirealms.craftengine.core.util.Key; @@ -31,11 +31,11 @@ public class BukkitAdvancementManager extends AbstractAdvancementManager { } @Override - public ConfigSectionParser parser() { + public ConfigParser parser() { return this.advancementParser; } - public class AdvancementParser implements ConfigSectionParser { + public class AdvancementParser implements ConfigParser { public static final String[] CONFIG_SECTION_NAME = new String[] {"advancements", "advancement"}; @Override 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 6142cbed6..3f6762964 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 @@ -25,7 +25,7 @@ import net.momirealms.craftengine.core.pack.ResourceLocation; import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.config.Config; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.plugin.locale.TranslationManager; import net.momirealms.craftengine.core.registry.BuiltInRegistries; @@ -193,7 +193,7 @@ public class BukkitBlockManager extends AbstractBlockManager { } @Override - public ConfigSectionParser parser() { + public ConfigParser parser() { return this.blockParser; } @@ -314,7 +314,7 @@ public class BukkitBlockManager extends AbstractBlockManager { } } - public class BlockParser implements ConfigSectionParser { + public class BlockParser implements ConfigParser { public static final String[] CONFIG_SECTION_NAME = new String[] {"blocks", "block"}; @Override diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java index 120430faa..4b79032ed 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java @@ -11,7 +11,7 @@ import net.momirealms.craftengine.core.loot.LootTable; import net.momirealms.craftengine.core.pack.LoadingSequence; import net.momirealms.craftengine.core.pack.Pack; import net.momirealms.craftengine.core.plugin.config.Config; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.sound.SoundData; import net.momirealms.craftengine.core.util.Key; @@ -86,11 +86,11 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager { } @Override - public ConfigSectionParser parser() { + public ConfigParser parser() { return this.furnitureParser; } - public class FurnitureParser implements ConfigSectionParser { + public class FurnitureParser implements ConfigParser { public static final String[] CONFIG_SECTION_NAME = new String[] { "furniture" }; @Override diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java index 9296dd4c5..9d72cbf8f 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java @@ -27,7 +27,7 @@ import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration; import net.momirealms.craftengine.core.pack.model.select.ChargeTypeSelectProperty; import net.momirealms.craftengine.core.pack.model.select.TrimMaterialSelectProperty; import net.momirealms.craftengine.core.plugin.config.Config; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.plugin.context.ContextHolder; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.registry.BuiltInRegistries; @@ -164,7 +164,7 @@ public class BukkitItemManager extends AbstractItemManager { } @Override - public ConfigSectionParser parser() { + public ConfigParser parser() { return this.itemParser; } @@ -224,7 +224,7 @@ public class BukkitItemManager extends AbstractItemManager { return wrapped.id(); } - public class ItemParser implements ConfigSectionParser { + public class ItemParser implements ConfigParser { public static final String[] CONFIG_SECTION_NAME = new String[] {"items", "item"}; @Override diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/loot/BukkitVanillaLootManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/loot/BukkitVanillaLootManager.java index f994c121b..5875827ee 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/loot/BukkitVanillaLootManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/loot/BukkitVanillaLootManager.java @@ -12,7 +12,7 @@ import net.momirealms.craftengine.core.loot.LootTable; import net.momirealms.craftengine.core.loot.VanillaLoot; import net.momirealms.craftengine.core.pack.LoadingSequence; import net.momirealms.craftengine.core.pack.Pack; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.plugin.context.ContextHolder; import net.momirealms.craftengine.core.plugin.context.parameter.CommonParameters; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; @@ -87,11 +87,11 @@ public class BukkitVanillaLootManager extends AbstractVanillaLootManager impleme } @Override - public ConfigSectionParser parser() { + public ConfigParser parser() { return this.vanillaLootParser; } - public class VanillaLootParser implements ConfigSectionParser { + public class VanillaLootParser implements ConfigParser { public static final String[] CONFIG_SECTION_NAME = new String[] {"vanilla-loots", "vanilla-loot", "loots", "loot"}; @Override diff --git a/core/src/main/java/net/momirealms/craftengine/core/advancement/AdvancementManager.java b/core/src/main/java/net/momirealms/craftengine/core/advancement/AdvancementManager.java index 0d2b8a2b0..b4a13703b 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/advancement/AdvancementManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/advancement/AdvancementManager.java @@ -1,9 +1,9 @@ package net.momirealms.craftengine.core.advancement; import net.momirealms.craftengine.core.plugin.Manageable; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; public interface AdvancementManager extends Manageable { - ConfigSectionParser parser(); + ConfigParser parser(); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/BlockManager.java b/core/src/main/java/net/momirealms/craftengine/core/block/BlockManager.java index 125f42018..8cbeb5a5a 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/BlockManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/BlockManager.java @@ -4,7 +4,7 @@ import com.google.gson.JsonElement; import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration; import net.momirealms.craftengine.core.pack.model.generation.ModelGenerator; import net.momirealms.craftengine.core.plugin.Manageable; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.util.Key; import org.incendo.cloud.suggestion.Suggestion; @@ -14,7 +14,7 @@ import java.util.Optional; public interface BlockManager extends Manageable, ModelGenerator { - ConfigSectionParser parser(); + ConfigParser parser(); Collection modelsToGenerate(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/FurnitureManager.java b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/FurnitureManager.java index d2692164d..2655d6804 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/FurnitureManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/FurnitureManager.java @@ -2,7 +2,7 @@ package net.momirealms.craftengine.core.entity.furniture; import net.momirealms.craftengine.core.entity.Entity; import net.momirealms.craftengine.core.plugin.Manageable; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.world.Vec3d; import net.momirealms.craftengine.core.world.World; @@ -15,7 +15,7 @@ import java.util.Optional; public interface FurnitureManager extends Manageable { String FURNITURE_ADMIN_NODE = "craftengine.furniture.admin"; - ConfigSectionParser parser(); + ConfigParser parser(); void initSuggestions(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java b/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java index aa7a7797e..6cd120eb1 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java @@ -6,7 +6,7 @@ import net.momirealms.craftengine.core.pack.LoadingSequence; import net.momirealms.craftengine.core.pack.Pack; import net.momirealms.craftengine.core.pack.ResourceLocation; import net.momirealms.craftengine.core.plugin.CraftEngine; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.plugin.context.ContextHolder; import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; @@ -75,8 +75,8 @@ public abstract class AbstractFontManager implements FontManager { } @Override - public ConfigSectionParser[] parsers() { - return new ConfigSectionParser[] {this.imageParser, this.emojiParser}; + public ConfigParser[] parsers() { + return new ConfigParser[] {this.imageParser, this.emojiParser}; } @Override @@ -339,7 +339,7 @@ public abstract class AbstractFontManager implements FontManager { return this.fonts.computeIfAbsent(key, Font::new); } - public class EmojiParser implements ConfigSectionParser { + public class EmojiParser implements ConfigParser { public static final String[] CONFIG_SECTION_NAME = new String[] {"emoji", "emojis"}; @Override @@ -400,7 +400,7 @@ public abstract class AbstractFontManager implements FontManager { } } - public class ImageParser implements ConfigSectionParser { + public class ImageParser implements ConfigParser { public static final String[] CONFIG_SECTION_NAME = new String[] {"images", "image"}; @Override diff --git a/core/src/main/java/net/momirealms/craftengine/core/font/FontManager.java b/core/src/main/java/net/momirealms/craftengine/core/font/FontManager.java index 95d2251d4..307350eea 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/font/FontManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/font/FontManager.java @@ -4,7 +4,7 @@ import net.kyori.adventure.text.Component; import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.plugin.Manageable; import net.momirealms.craftengine.core.plugin.config.Config; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.util.AdventureHelper; import net.momirealms.craftengine.core.util.CharacterUtils; import net.momirealms.craftengine.core.util.FormatUtils; @@ -45,7 +45,7 @@ public interface FontManager extends Manageable { IllegalCharacterProcessResult processIllegalCharacters(String raw, char replacement); - ConfigSectionParser[] parsers(); + ConfigParser[] parsers(); default EmojiTextProcessResult replaceMiniMessageEmoji(@NotNull String miniMessage, @Nullable Player player) { return replaceMiniMessageEmoji(miniMessage, player, Config.maxEmojisPerParse()); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java index f3ed35781..c02f1aa54 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java @@ -7,7 +7,7 @@ import net.momirealms.craftengine.core.pack.model.ItemModel; import net.momirealms.craftengine.core.pack.model.LegacyOverridesModel; import net.momirealms.craftengine.core.pack.model.generation.ModelGenerator; import net.momirealms.craftengine.core.plugin.Manageable; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.util.Key; import org.incendo.cloud.suggestion.Suggestion; @@ -17,7 +17,7 @@ import java.util.*; public interface ItemManager extends Manageable, ModelGenerator { - ConfigSectionParser parser(); + ConfigParser parser(); Map> legacyItemOverrides(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeManager.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeManager.java index 7220614c4..f84e496ec 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeManager.java @@ -9,7 +9,7 @@ import net.momirealms.craftengine.core.pack.LoadingSequence; import net.momirealms.craftengine.core.pack.Pack; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.config.Config; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.util.Key; @@ -35,7 +35,7 @@ public abstract class AbstractRecipeManager implements RecipeManager { } @Override - public ConfigSectionParser parser() { + public ConfigParser parser() { return this.recipeParser; } @@ -140,7 +140,7 @@ public abstract class AbstractRecipeManager implements RecipeManager { } } - public class RecipeParser implements ConfigSectionParser { + public class RecipeParser implements ConfigParser { public static final String[] CONFIG_SECTION_NAME = new String[] {"recipes", "recipe"}; @Override diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeManager.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeManager.java index eb59f67ed..c1fdcdbc3 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/RecipeManager.java @@ -2,7 +2,7 @@ package net.momirealms.craftengine.core.item.recipe; import net.momirealms.craftengine.core.item.recipe.input.RecipeInput; import net.momirealms.craftengine.core.plugin.Manageable; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.util.Key; import org.jetbrains.annotations.Nullable; @@ -11,7 +11,7 @@ import java.util.Optional; public interface RecipeManager extends Manageable { - ConfigSectionParser parser(); + ConfigParser parser(); boolean isDataPackRecipe(Key key); diff --git a/core/src/main/java/net/momirealms/craftengine/core/loot/VanillaLootManager.java b/core/src/main/java/net/momirealms/craftengine/core/loot/VanillaLootManager.java index c4fabdf8d..65ece069d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/loot/VanillaLootManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/loot/VanillaLootManager.java @@ -1,14 +1,14 @@ package net.momirealms.craftengine.core.loot; import net.momirealms.craftengine.core.plugin.Manageable; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.util.Key; import java.util.Optional; public interface VanillaLootManager extends Manageable { - ConfigSectionParser parser(); + ConfigParser parser(); Optional getBlockLoot(int blockState); 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 b582cb7d9..cfbbf3810 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 @@ -19,7 +19,7 @@ import net.momirealms.craftengine.core.pack.model.generation.ModelGenerator; import net.momirealms.craftengine.core.pack.obfuscation.ObfA; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.config.Config; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.plugin.config.StringKeyConstructor; import net.momirealms.craftengine.core.plugin.locale.I18NData; import net.momirealms.craftengine.core.plugin.locale.LocalizedException; @@ -70,8 +70,8 @@ public abstract class AbstractPackManager implements PackManager { private final CraftEngine plugin; private final BiConsumer eventDispatcher; private final Map loadedPacks = new HashMap<>(); - private final Map sectionParsers = new HashMap<>(); - private final TreeMap> cachedConfigs = new TreeMap<>(); + private final Map sectionParsers = new HashMap<>(); + private final TreeMap> cachedConfigs = new TreeMap<>(); protected BiConsumer zipGenerator; protected ResourcePackHost resourcePackHost; @@ -211,7 +211,7 @@ public abstract class AbstractPackManager implements PackManager { } @Override - public boolean registerConfigSectionParser(ConfigSectionParser parser) { + public boolean registerConfigSectionParser(ConfigParser parser) { for (String id : parser.sectionId()) { if (this.sectionParsers.containsKey(id)) return false; } @@ -404,7 +404,7 @@ public abstract class AbstractPackManager implements PackManager { plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/gui/sprites/tooltip/topaz_frame.png.mcmeta"); } - private void loadResourceConfigs(Predicate predicate) { + private void loadResourceConfigs(Predicate predicate) { long o1 = System.nanoTime(); for (Pack pack : loadedPacks()) { if (!pack.enabled()) continue; @@ -435,8 +435,8 @@ public abstract class AbstractPackManager implements PackManager { } long o2 = System.nanoTime(); this.plugin.logger().info("Loaded packs. Took " + String.format("%.2f", ((o2 - o1) / 1_000_000.0)) + " ms"); - for (Map.Entry> entry : this.cachedConfigs.entrySet()) { - ConfigSectionParser parser = entry.getKey(); + for (Map.Entry> entry : this.cachedConfigs.entrySet()) { + ConfigParser parser = entry.getKey(); long t1 = System.nanoTime(); for (CachedConfig cached : entry.getValue()) { for (Map.Entry configEntry : cached.config().entrySet()) { @@ -444,8 +444,8 @@ public abstract class AbstractPackManager implements PackManager { try { Key id = Key.withDefaultNamespace(key, cached.pack().namespace()); try { - if (parser.isTemplate()) { - this.plugin.templateManager().addTemplate(cached.pack(), cached.filePath(), id, configEntry.getValue()); + if (parser.supportsParsingObject()) { + parser.parseObject(cached.pack(), cached.filePath(), id, configEntry.getValue()); } else if (predicate.test(parser)) { if (configEntry.getValue() instanceof Map configSection0) { Map configSection1 = castToMap(configSection0, false); diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/LoadingSequence.java b/core/src/main/java/net/momirealms/craftengine/core/pack/LoadingSequence.java index 104508c8c..b684aa54f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/LoadingSequence.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/LoadingSequence.java @@ -2,17 +2,18 @@ package net.momirealms.craftengine.core.pack; public class LoadingSequence { public static final int TEMPLATE = 0; - public static final int LANG = 10; - public static final int TRANSLATION = 20; - public static final int BLOCK = 30; - public static final int ITEM = 40; - public static final int FURNITURE = 50; - public static final int IMAGE = 60; - public static final int RECIPE = 70; - public static final int CATEGORY = 80; - public static final int SOUND = 90; - public static final int JUKEBOX_SONG = 100; - public static final int VANILLA_LOOTS = 110; - public static final int EMOJI = 120; - public static final int ADVANCEMENT = 130; + public static final int GLOBAL_VAR = 10; + public static final int LANG = 20; + public static final int TRANSLATION = 30; + public static final int BLOCK = 40; + public static final int ITEM = 50; + public static final int FURNITURE = 60; + public static final int IMAGE = 70; + public static final int RECIPE = 80; + public static final int CATEGORY = 90; + public static final int SOUND = 100; + public static final int JUKEBOX_SONG = 110; + public static final int VANILLA_LOOTS = 120; + public static final int EMOJI = 130; + public static final int ADVANCEMENT = 140; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/PackManager.java b/core/src/main/java/net/momirealms/craftengine/core/pack/PackManager.java index 0734ded69..44641827a 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/PackManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/PackManager.java @@ -3,7 +3,7 @@ package net.momirealms.craftengine.core.pack; import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.pack.host.ResourcePackHost; import net.momirealms.craftengine.core.plugin.Manageable; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import org.jetbrains.annotations.NotNull; import java.nio.file.Path; @@ -16,17 +16,17 @@ public interface PackManager extends Manageable { @NotNull Collection loadedPacks(); - boolean registerConfigSectionParser(ConfigSectionParser parser); + boolean registerConfigSectionParser(ConfigParser parser); - default void registerConfigSectionParsers(ConfigSectionParser[] parsers) { - for (ConfigSectionParser parser : parsers) { + default void registerConfigSectionParsers(ConfigParser[] parsers) { + for (ConfigParser parser : parsers) { registerConfigSectionParser(parser); } } boolean unregisterConfigSectionParser(String id); - default void unregisterConfigSectionParser(ConfigSectionParser parser) { + default void unregisterConfigSectionParser(ConfigParser parser) { for (String id : parser.sectionId()) { unregisterConfigSectionParser(id); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/CompatibilityManager.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/CompatibilityManager.java index b6f1d0794..7749be015 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/CompatibilityManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/CompatibilityManager.java @@ -27,5 +27,7 @@ public interface CompatibilityManager { String parse(Player player, String text); + String parse(Player player1, Player player2, String text); + int getPlayerProtocolVersion(UUID uuid); } 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 64fa38f73..51e975b79 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 @@ -14,6 +14,7 @@ import net.momirealms.craftengine.core.plugin.command.sender.SenderFactory; import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.plugin.config.template.TemplateManager; import net.momirealms.craftengine.core.plugin.config.template.TemplateManagerImpl; +import net.momirealms.craftengine.core.plugin.context.GlobalVariableManager; import net.momirealms.craftengine.core.plugin.dependency.Dependencies; import net.momirealms.craftengine.core.plugin.dependency.Dependency; import net.momirealms.craftengine.core.plugin.dependency.DependencyManager; @@ -68,6 +69,7 @@ public abstract class CraftEngine implements Plugin { protected VanillaLootManager vanillaLootManager; protected AdvancementManager advancementManager; protected CompatibilityManager compatibilityManager; + protected GlobalVariableManager globalVariableManager; private final Consumer reloadEventDispatcher; private boolean isReloading; @@ -133,6 +135,7 @@ public abstract class CraftEngine implements Plugin { this.translationManager.reload(); // clear the outdated cache by reloading the managers this.templateManager.reload(); + this.globalVariableManager.reload(); this.furnitureManager.reload(); this.fontManager.reload(); this.itemManager.reload(); @@ -198,6 +201,7 @@ public abstract class CraftEngine implements Plugin { this.isInitializing = true; this.networkManager.init(); this.templateManager = new TemplateManagerImpl(); + this.globalVariableManager = new GlobalVariableManager(); this.itemBrowserManager = new ItemBrowserManagerImpl(this); this.commandManager.registerDefaultFeatures(); // delay the reload so other plugins can register some custom parsers @@ -245,6 +249,7 @@ public abstract class CraftEngine implements Plugin { if (this.soundManager != null) this.soundManager.disable(); if (this.vanillaLootManager != null) this.vanillaLootManager.disable(); if (this.translationManager != null) this.translationManager.disable(); + if (this.globalVariableManager != null) this.globalVariableManager.disable(); if (this.scheduler != null) this.scheduler.shutdownScheduler(); if (this.scheduler != null) this.scheduler.shutdownExecutor(); if (this.commandManager != null) this.commandManager.unregisterFeatures(); @@ -255,6 +260,8 @@ public abstract class CraftEngine implements Plugin { protected void registerDefaultParsers() { // register template parser this.packManager.registerConfigSectionParser(this.templateManager.parser()); + // register global variables parser + this.packManager.registerConfigSectionParser(this.globalVariableManager.parser()); // register font parser this.packManager.registerConfigSectionParsers(this.fontManager.parsers()); // register item parser @@ -430,6 +437,11 @@ public abstract class CraftEngine implements Plugin { return compatibilityManager; } + @Override + public GlobalVariableManager globalVariableManager() { + return globalVariableManager; + } + @Override public Platform platform() { return platform; diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/Plugin.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/Plugin.java index 37ef07865..1dde1374e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/Plugin.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/Plugin.java @@ -12,6 +12,7 @@ import net.momirealms.craftengine.core.plugin.classpath.ClassPathAppender; import net.momirealms.craftengine.core.plugin.command.sender.SenderFactory; import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.plugin.config.template.TemplateManager; +import net.momirealms.craftengine.core.plugin.context.GlobalVariableManager; import net.momirealms.craftengine.core.plugin.dependency.DependencyManager; import net.momirealms.craftengine.core.plugin.gui.GuiManager; import net.momirealms.craftengine.core.plugin.gui.category.ItemBrowserManager; @@ -91,5 +92,7 @@ public interface Plugin { CompatibilityManager compatibilityManager(); + GlobalVariableManager globalVariableManager(); + Platform platform(); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/ConfigSectionParser.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/ConfigParser.java similarity index 52% rename from core/src/main/java/net/momirealms/craftengine/core/plugin/config/ConfigSectionParser.java rename to core/src/main/java/net/momirealms/craftengine/core/plugin/config/ConfigParser.java index 0c7f94f94..4d6fae451 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/ConfigSectionParser.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/ConfigParser.java @@ -8,20 +8,25 @@ import org.jetbrains.annotations.NotNull; import java.nio.file.Path; import java.util.Map; -public interface ConfigSectionParser extends Comparable { +public interface ConfigParser extends Comparable { String[] sectionId(); - void parseSection(Pack pack, Path path, Key id, Map section) throws LocalizedException; + default void parseSection(Pack pack, Path path, Key id, Map section) throws LocalizedException { + this.parseObject(pack, path, id, section); + } + + default void parseObject(Pack pack, Path path, Key id, Object object) throws LocalizedException { + } int loadingSequence(); - default boolean isTemplate() { + default boolean supportsParsingObject() { return false; } @Override - default int compareTo(@NotNull ConfigSectionParser another) { + default int compareTo(@NotNull ConfigParser another) { return Integer.compare(loadingSequence(), another.loadingSequence()); } } 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 b6b2b00be..01f24d80e 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 @@ -1,11 +1,8 @@ package net.momirealms.craftengine.core.plugin.config.template; -import net.momirealms.craftengine.core.pack.Pack; import net.momirealms.craftengine.core.plugin.Manageable; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; -import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; -import java.nio.file.Path; import java.util.Map; import java.util.regex.Pattern; @@ -17,9 +14,7 @@ public interface TemplateManager extends Manageable { String OVERRIDES = "overrides"; String ARGUMENTS = "arguments"; - ConfigSectionParser parser(); - - void addTemplate(Pack pack, Path path, Key id, Object obj); + ConfigParser parser(); Map applyTemplates(Map input); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java index 080dfa9ba..8eda9774e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java @@ -2,7 +2,7 @@ package net.momirealms.craftengine.core.plugin.config.template; import net.momirealms.craftengine.core.pack.LoadingSequence; import net.momirealms.craftengine.core.pack.Pack; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.GsonHelper; import net.momirealms.craftengine.core.util.Key; @@ -24,7 +24,7 @@ public class TemplateManagerImpl implements TemplateManager { this.templateParser = new TemplateParser(); } - public class TemplateParser implements ConfigSectionParser { + public class TemplateParser implements ConfigParser { public static final String[] CONFIG_SECTION_NAME = new String[] {"templates", "template"}; @Override @@ -38,13 +38,16 @@ public class TemplateManagerImpl implements TemplateManager { } @Override - public boolean isTemplate() { + public boolean supportsParsingObject() { return true; } @Override - public void parseSection(Pack pack, Path path, Key id, Map section) { - addTemplate(pack, path, id, section); + public void parseObject(Pack pack, Path path, Key id, Object obj) { + if (templates.containsKey(id)) { + throw new LocalizedResourceConfigException("warning.config.template.duplicate", path.toString(), id.toString()); + } + templates.put(id, obj); } } @@ -54,18 +57,10 @@ public class TemplateManagerImpl implements TemplateManager { } @Override - public ConfigSectionParser parser() { + public ConfigParser parser() { return this.templateParser; } - @Override - public void addTemplate(Pack pack, Path path, Key id, Object obj) { - if (this.templates.containsKey(id)) { - throw new LocalizedResourceConfigException("warning.config.template.duplicate", path.toString(), id.toString()); - } - this.templates.put(id, obj); - } - @Override public Map applyTemplates(Map input) { Objects.requireNonNull(input, "Input must not be null"); diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/AbstractCommonContext.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/AbstractCommonContext.java index 4717ae0e0..1863c0ab8 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/AbstractCommonContext.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/AbstractCommonContext.java @@ -24,7 +24,7 @@ public abstract class AbstractCommonContext implements Context { public TagResolver[] tagResolvers() { if (this.tagResolvers == null) { this.tagResolvers = new TagResolver[]{ShiftTag.INSTANCE, ImageTag.INSTANCE, new I18NTag(this), new NamedArgumentTag(this), - new PlaceholderTag(null), new ExpressionTag(this)}; + new PlaceholderTag(null), new ExpressionTag(this), new GlobalVariableTag(this)}; } return this.tagResolvers; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/GlobalVariableManager.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/GlobalVariableManager.java new file mode 100644 index 000000000..5c29100a9 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/GlobalVariableManager.java @@ -0,0 +1,57 @@ +package net.momirealms.craftengine.core.plugin.context; + +import net.momirealms.craftengine.core.pack.LoadingSequence; +import net.momirealms.craftengine.core.pack.Pack; +import net.momirealms.craftengine.core.plugin.Manageable; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; +import net.momirealms.craftengine.core.plugin.locale.LocalizedException; +import org.jetbrains.annotations.Nullable; + +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; + +public class GlobalVariableManager implements Manageable { + private final Map globalVariables = new HashMap<>(); + private final GlobalVariableParser parser = new GlobalVariableParser(); + + @Nullable + public String get(final String key) { + return this.globalVariables.get(key); + } + + @Override + public void unload() { + this.globalVariables.clear(); + } + + public ConfigParser parser() { + return this.parser; + } + + public class GlobalVariableParser implements ConfigParser { + public static final String[] CONFIG_SECTION_NAME = new String[] {"global-variables", "global-variable"}; + + @Override + public int loadingSequence() { + return LoadingSequence.GLOBAL_VAR; + } + + @Override + public String[] sectionId() { + return CONFIG_SECTION_NAME; + } + + @Override + public boolean supportsParsingObject() { + return true; + } + + @Override + public void parseObject(Pack pack, Path path, net.momirealms.craftengine.core.util.Key id, Object object) throws LocalizedException { + if (object != null) { + globalVariables.put(id.value(), object.toString()); + } + } + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/PlayerOptionalContext.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/PlayerOptionalContext.java index e471cc51a..ac63f07c9 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/PlayerOptionalContext.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/PlayerOptionalContext.java @@ -48,11 +48,16 @@ public class PlayerOptionalContext extends AbstractAdditionalParameterContext im return this.player; } + public boolean isPlayerPresent() { + return this.player != null; + } + @Override @NotNull public TagResolver[] tagResolvers() { if (this.tagResolvers == null) { - this.tagResolvers = new TagResolver[]{ShiftTag.INSTANCE, ImageTag.INSTANCE, new PlaceholderTag(this.player), new I18NTag(this), new NamedArgumentTag(this), new ExpressionTag(this)}; + this.tagResolvers = new TagResolver[]{ShiftTag.INSTANCE, ImageTag.INSTANCE, new PlaceholderTag(this.player), new I18NTag(this), + new NamedArgumentTag(this), new ExpressionTag(this), new GlobalVariableTag(this)}; } return this.tagResolvers; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/ViewerContext.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/ViewerContext.java index 4591d242d..cc4f2d761 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/ViewerContext.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/ViewerContext.java @@ -57,10 +57,18 @@ public class ViewerContext implements RelationalContext { if (this.owner instanceof PlayerOptionalContext context) { optionalOwner = context.player(); } - this.tagResolvers = new TagResolver[]{ShiftTag.INSTANCE, ImageTag.INSTANCE, - new PlaceholderTag(optionalOwner), new ViewerPlaceholderTag(this.viewer.player()), - new NamedArgumentTag(this.owner), new ViewerNamedArgumentTag(this.viewer), - new I18NTag(this), new ExpressionTag(this)}; + if (optionalOwner != null && this.viewer.player != null) { + this.tagResolvers = new TagResolver[]{new RelationalPlaceholderTag(optionalOwner, this.viewer.player), + ShiftTag.INSTANCE, ImageTag.INSTANCE, + new PlaceholderTag(optionalOwner), new ViewerPlaceholderTag(this.viewer.player()), + new NamedArgumentTag(this.owner), new ViewerNamedArgumentTag(this.viewer), + new I18NTag(this), new ExpressionTag(this), new GlobalVariableTag(this)}; + } else { + this.tagResolvers = new TagResolver[]{ShiftTag.INSTANCE, ImageTag.INSTANCE, + new PlaceholderTag(optionalOwner), new ViewerPlaceholderTag(this.viewer.player()), + new NamedArgumentTag(this.owner), new ViewerNamedArgumentTag(this.viewer), + new I18NTag(this), new ExpressionTag(this), new GlobalVariableTag(this)}; + } } return this.tagResolvers; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManager.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManager.java index e9de45dab..9d6b9732b 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManager.java @@ -5,7 +5,7 @@ import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.item.recipe.Recipe; import net.momirealms.craftengine.core.plugin.Manageable; import net.momirealms.craftengine.core.plugin.config.Config; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.plugin.gui.Gui; import net.momirealms.craftengine.core.util.Key; @@ -19,7 +19,7 @@ public interface ItemBrowserManager extends Manageable { int MAX_RECIPE_DEPTH = 16; String GET_ITEM_PERMISSION = "craftengine.browser.get_item"; - ConfigSectionParser parser(); + ConfigParser parser(); void addExternalCategoryMember(Key item, List category); diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManagerImpl.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManagerImpl.java index 9d6f17d16..024b294df 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManagerImpl.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManagerImpl.java @@ -8,7 +8,7 @@ import net.momirealms.craftengine.core.item.recipe.*; import net.momirealms.craftengine.core.pack.LoadingSequence; import net.momirealms.craftengine.core.pack.Pack; import net.momirealms.craftengine.core.plugin.CraftEngine; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.plugin.context.ContextHolder; import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext; import net.momirealms.craftengine.core.plugin.gui.*; @@ -68,7 +68,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { } @Override - public ConfigSectionParser parser() { + public ConfigParser parser() { return this.categoryParser; } @@ -93,7 +93,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { return Optional.ofNullable(this.byId.get(key)); } - public class CategoryParser implements ConfigSectionParser { + public class CategoryParser implements ConfigParser { public static final String[] CONFIG_SECTION_NAME = new String[] {"categories", "category"}; @Override diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/TranslationManager.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/TranslationManager.java index f8bab04f3..d4ec4c773 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/TranslationManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/TranslationManager.java @@ -3,7 +3,7 @@ package net.momirealms.craftengine.core.plugin.locale; import net.kyori.adventure.text.Component; import net.kyori.adventure.translation.Translator; import net.momirealms.craftengine.core.plugin.Manageable; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -44,7 +44,7 @@ public interface TranslationManager extends Manageable { return TranslationManagerImpl.instance; } - ConfigSectionParser[] parsers(); + ConfigParser[] parsers(); default String miniMessageTranslation(String key) { return miniMessageTranslation(key, null); diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/TranslationManagerImpl.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/TranslationManagerImpl.java index dbbcdd70c..d73c40551 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/TranslationManagerImpl.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/TranslationManagerImpl.java @@ -7,7 +7,7 @@ import net.momirealms.craftengine.core.pack.Pack; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.Plugin; import net.momirealms.craftengine.core.plugin.PluginProperties; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.plugin.config.StringKeyConstructor; import net.momirealms.craftengine.core.plugin.text.minimessage.IndexedArgumentTag; import net.momirealms.craftengine.core.util.AdventureHelper; @@ -63,8 +63,8 @@ public class TranslationManagerImpl implements TranslationManager { } @Override - public ConfigSectionParser[] parsers() { - return new ConfigSectionParser[] {this.langParser, this.i18nParser}; + public ConfigParser[] parsers() { + return new ConfigParser[] {this.langParser, this.i18nParser}; } @Override @@ -277,7 +277,7 @@ public class TranslationManagerImpl implements TranslationManager { } } - public class I18NParser implements ConfigSectionParser { + public class I18NParser implements ConfigParser { public static final String[] CONFIG_SECTION_NAME = new String[] {"i18n", "internationalization", "translation", "translations"}; @Override @@ -308,7 +308,7 @@ public class TranslationManagerImpl implements TranslationManager { } } - public class LangParser implements ConfigSectionParser { + public class LangParser implements ConfigParser { public static final String[] CONFIG_SECTION_NAME = new String[] {"lang", "language", "languages"}; @Override diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/GlobalVariableTag.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/GlobalVariableTag.java new file mode 100644 index 000000000..0a7602b0e --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/GlobalVariableTag.java @@ -0,0 +1,38 @@ +package net.momirealms.craftengine.core.plugin.text.minimessage; + +import net.kyori.adventure.text.minimessage.ParsingException; +import net.kyori.adventure.text.minimessage.tag.Tag; +import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.context.Context; +import net.momirealms.craftengine.core.plugin.locale.TranslationManager; +import net.momirealms.craftengine.core.util.AdventureHelper; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class GlobalVariableTag implements TagResolver { + private final Context context; + + public GlobalVariableTag(Context context) { + this.context = context; + } + + @Override + public @Nullable Tag resolve(@NotNull String name, @NotNull ArgumentQueue arguments, @NotNull net.kyori.adventure.text.minimessage.Context ctx) throws ParsingException { + if (!this.has(name)) { + return null; + } + String id = arguments.popOr("No argument variable id provided").toString(); + String value = CraftEngine.instance().globalVariableManager().get(id); + if (value == null) { + throw ctx.newException("Unknown variable: ", arguments); + } + return Tag.selfClosingInserting(AdventureHelper.miniMessage().deserialize(value, this.context.tagResolvers())); + } + + @Override + public boolean has(@NotNull String name) { + return "global".equals(name); + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/RelationalPlaceholderTag.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/RelationalPlaceholderTag.java new file mode 100644 index 000000000..07f175b6d --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/RelationalPlaceholderTag.java @@ -0,0 +1,40 @@ +package net.momirealms.craftengine.core.plugin.text.minimessage; + +import net.kyori.adventure.text.minimessage.Context; +import net.kyori.adventure.text.minimessage.ParsingException; +import net.kyori.adventure.text.minimessage.tag.Tag; +import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import net.momirealms.craftengine.core.entity.player.Player; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.util.AdventureHelper; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class RelationalPlaceholderTag implements TagResolver { + private final Player player1; + private final Player player2; + + public RelationalPlaceholderTag(@NotNull Player player1, @NotNull Player player2) { + this.player1 = player1; + this.player2 = player2; + } + + @Override + public @Nullable Tag resolve(@NotNull String name, @NotNull ArgumentQueue arguments, @NotNull Context ctx) throws ParsingException { + if (!this.has(name) || !CraftEngine.instance().compatibilityManager().hasPlaceholderAPI()) { + return null; + } + String placeholder = "%" + arguments.popOr("No argument placeholder provided") + "%"; + String parsed = CraftEngine.instance().compatibilityManager().parse(player1, player2, placeholder); + if (parsed.equals(placeholder)) { + parsed = arguments.popOr("No default papi value provided").toString(); + } + return Tag.selfClosingInserting(AdventureHelper.miniMessage().deserialize(parsed)); + } + + @Override + public boolean has(@NotNull String name) { + return "rel_papi".equals(name); + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/sound/AbstractSoundManager.java b/core/src/main/java/net/momirealms/craftengine/core/sound/AbstractSoundManager.java index 789aa65d8..d75ee7ec8 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/sound/AbstractSoundManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/sound/AbstractSoundManager.java @@ -4,7 +4,7 @@ import net.kyori.adventure.text.Component; import net.momirealms.craftengine.core.pack.LoadingSequence; import net.momirealms.craftengine.core.pack.Pack; import net.momirealms.craftengine.core.plugin.CraftEngine; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.util.*; @@ -32,8 +32,8 @@ public abstract class AbstractSoundManager implements SoundManager { } @Override - public ConfigSectionParser[] parsers() { - return new ConfigSectionParser[] { this.soundParser, this.songParser }; + public ConfigParser[] parsers() { + return new ConfigParser[] { this.soundParser, this.songParser }; } @Override @@ -59,7 +59,7 @@ public abstract class AbstractSoundManager implements SoundManager { protected abstract void registerSongs(Map songs); - public class SongParser implements ConfigSectionParser { + public class SongParser implements ConfigParser { public static final String[] CONFIG_SECTION_NAME = new String[] {"jukebox_songs", "song", "songs", "jukebox", "jukebox_song"}; @Override @@ -86,7 +86,7 @@ public abstract class AbstractSoundManager implements SoundManager { } } - public class SoundParser implements ConfigSectionParser { + public class SoundParser implements ConfigParser { public static final String[] CONFIG_SECTION_NAME = new String[] {"sounds", "sound"}; @Override diff --git a/core/src/main/java/net/momirealms/craftengine/core/sound/SoundManager.java b/core/src/main/java/net/momirealms/craftengine/core/sound/SoundManager.java index 54450acd5..55eeb6e4b 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/sound/SoundManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/sound/SoundManager.java @@ -1,7 +1,7 @@ package net.momirealms.craftengine.core.sound; import net.momirealms.craftengine.core.plugin.Manageable; -import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; +import net.momirealms.craftengine.core.plugin.config.ConfigParser; import net.momirealms.craftengine.core.util.Key; import java.util.Map; @@ -10,7 +10,7 @@ public interface SoundManager extends Manageable { boolean isVanillaSoundEvent(Key key); - ConfigSectionParser[] parsers(); + ConfigParser[] parsers(); Map sounds(); } From a705a8e8de3f1d33d2fe80f8f2a2e080ec896820 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Fri, 9 May 2025 22:39:40 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E5=A2=9E=E5=BC=BAgeneration=E7=9A=84?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../default/configuration/categories.yml | 4 +- .../resources/default/configuration/items.yml | 35 ++- .../src/main/resources/translations/en.yml | 2 + .../src/main/resources/translations/zh_cn.yml | 2 + .../bukkit/block/BukkitBlockManager.java | 2 +- .../bukkit/item/BukkitItemManager.java | 6 + .../core/pack/AbstractPackManager.java | 2 +- .../core/pack/model/BaseItemModel.java | 2 +- .../core/pack/model/SpecialItemModel.java | 3 +- .../generation/AbstractModelGenerator.java | 9 +- .../core/pack/model/generation/GuiLight.java | 5 + .../model/generation/ModelGeneration.java | 228 +++++++++++++++--- .../model/generation/display/DisplayMeta.java | 25 ++ .../generation/display/DisplayPosition.java | 12 + .../model/special/ShulkerBoxSpecialModel.java | 1 - .../text/minimessage/GlobalVariableTag.java | 1 - 16 files changed, 295 insertions(+), 44 deletions(-) create mode 100644 core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/GuiLight.java create mode 100644 core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/display/DisplayMeta.java create mode 100644 core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/display/DisplayPosition.java diff --git a/bukkit/loader/src/main/resources/resources/default/configuration/categories.yml b/bukkit/loader/src/main/resources/resources/default/configuration/categories.yml index 3c8d218d6..3189f43a4 100644 --- a/bukkit/loader/src/main/resources/resources/default/configuration/categories.yml +++ b/bukkit/loader/src/main/resources/resources/default/configuration/categories.yml @@ -62,4 +62,6 @@ categories: - default:flame_cane - default:gunpowder_block - default:solid_gunpowder_block - - default:ender_pearl_flower_seeds \ No newline at end of file + - default:ender_pearl_flower_seeds + - default:gui_head_size_1 + - default:gui_head_size_4 \ No newline at end of file diff --git a/bukkit/loader/src/main/resources/resources/default/configuration/items.yml b/bukkit/loader/src/main/resources/resources/default/configuration/items.yml index 02fa220c0..b21baa96f 100644 --- a/bukkit/loader/src/main/resources/resources/default/configuration/items.yml +++ b/bukkit/loader/src/main/resources/resources/default/configuration/items.yml @@ -1,4 +1,37 @@ -items: +items#gui_head: + default:gui_head_size_1: + material: player_head + custom-model-data: 1000 + model: + type: minecraft:special + path: minecraft:item/custom/gui_head_size_1 + generation: + parent: minecraft:item/template_skull + gui-light: front + display: + gui: + translation: 0,8,0 + scale: 2,2,2 + model: + type: minecraft:head + kind: player + default:gui_head_size_4: + material: player_head + custom-model-data: 1001 + model: + type: minecraft:special + path: minecraft:item/custom/gui_head_size_4 + generation: + parent: minecraft:item/template_skull + gui-light: front + display: + gui: + translation: 9,7,0 + scale: 4,4,4 + model: + type: minecraft:head + kind: player +items#topaz_gears: default:topaz_rod: material: fishing_rod custom-model-data: 1000 diff --git a/bukkit/loader/src/main/resources/translations/en.yml b/bukkit/loader/src/main/resources/translations/en.yml index d7240fa55..3f0da67b9 100644 --- a/bukkit/loader/src/main/resources/translations/en.yml +++ b/bukkit/loader/src/main/resources/translations/en.yml @@ -227,6 +227,8 @@ warning.config.block.behavior.strippable.missing_stripped: "Issue found warning.config.block.event.condition.missing_type: "Issue found in file - The block '' is missing the required 'type' argument for event condition." warning.config.block.event.condition.invalid_type: "Issue found in file - The block '' is using an invalid 'type' argument '' for event condition." warning.config.model.generation.missing_parent: "Issue found in file - The config '' is missing the required 'parent' argument in 'generation' section." +warning.config.model.generation.invalid_display_position: "Issue found in file - The config '' is using an invalid display position '' in 'generation.display' section. Allowed display positions: []" +warning.config.model.generation.invalid_gui_light: "Issue found in file - The config '' is using an invalid gui-light option '' in 'generation' section. Allowed gui light options: []" warning.config.model.generation.conflict: "Issue found in file - Failed to generate model for '' as two or more configurations attempt to generate different json models with the same path: ''." warning.config.model.generation.texture.invalid: "Issue found in file - The config '' has a texture '' with path '' that contains illegal characters. Please read https://minecraft.wiki/w/Resource_location#Legal_characters." warning.config.model.generation.parent.invalid: "Issue found in file - The config '' has a parent argument '' that contains illegal characters. Please read https://minecraft.wiki/w/Resource_location#Legal_characters." diff --git a/bukkit/loader/src/main/resources/translations/zh_cn.yml b/bukkit/loader/src/main/resources/translations/zh_cn.yml index 2429e0ff3..9a75a659e 100644 --- a/bukkit/loader/src/main/resources/translations/zh_cn.yml +++ b/bukkit/loader/src/main/resources/translations/zh_cn.yml @@ -228,6 +228,8 @@ warning.config.block.event.condition.missing_type: "在文件 - warning.config.block.event.condition.invalid_type: "在文件 - 方块 '' 使用了无效的事件条件类型 ''" warning.config.model.generation.missing_parent: "在文件 发现问题 - 配置项 '' 的 'generation' 段落缺少必需的 'parent' 参数" warning.config.model.generation.conflict: "在文件 发现问题 - 无法为 '' 生成模型 存在多个配置尝试使用相同路径 '' 生成不同的 JSON 模型" +warning.config.model.generation.invalid_display_position: "在文件 发现问题 - 配置项 '' 在 'generation.display' 区域使用了无效的 display 位置类型 ''. 可用展示类型: []" +warning.config.model.generation.invalid_gui_light: "在文件 发现问题 - 配置项 '' 在 'generation' 区域使用了无效的GUI光照 ''. 可用GUI光照: []" warning.config.model.generation.texture.invalid: "在文件 发现问题 - 配置项 '' 的纹理 '' 路径 '' 包含非法字符 请参考 https://zh.minecraft.wiki/w/%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4ID#%E5%90%88%E6%B3%95%E5%AD%97%E7%AC%A6" warning.config.model.generation.parent.invalid: "在文件 发现问题 - 配置项 '' 的父级参数 '' 包含非法字符 请参考 https://zh.minecraft.wiki/w/%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4ID#%E5%90%88%E6%B3%95%E5%AD%97%E7%AC%A6" warning.config.emoji.missing_keywords: "在文件 发现问题 - 表情 '' 缺少必需的 'keywords' 参数" 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 3f6762964..8bd60c4c7 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 @@ -537,7 +537,7 @@ public class BukkitBlockManager extends AbstractBlockManager { if (singleModelMap.containsKey("weight")) json.addProperty("weight", ResourceConfigUtils.getAsInt(singleModelMap.get("weight"), "weight")); Map generationMap = MiscUtils.castToMap(singleModelMap.get("generation"), true); if (generationMap != null) { - prepareModelGeneration(new ModelGeneration(Key.of(modelPath), generationMap)); + prepareModelGeneration(ModelGeneration.of(Key.of(modelPath), generationMap)); } variants.add(json); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java index 9d72cbf8f..fe46abf8e 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java @@ -463,6 +463,12 @@ public class BukkitItemManager extends AbstractItemManager { baseModel.path(), customModelData )); + } else if (currentModel instanceof SpecialItemModel specialModel) { + resultList.add(new LegacyOverridesModel( + new LinkedHashMap<>(accumulatedPredicates), + specialModel.base(), + customModelData + )); } } 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 cfbbf3810..a4a02839d 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 @@ -832,7 +832,7 @@ public abstract class AbstractPackManager implements PackManager { } try (BufferedWriter writer = Files.newBufferedWriter(modelPath)) { - GsonHelper.get().toJson(generation.getJson(), writer); + GsonHelper.get().toJson(generation.get(), writer); } catch (IOException e) { plugin.logger().warn("Failed to generate model: " + modelPath.toAbsolutePath(), e); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/BaseItemModel.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/BaseItemModel.java index 4b2609c3b..1756b6b14 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/BaseItemModel.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/BaseItemModel.java @@ -77,7 +77,7 @@ public class BaseItemModel implements ItemModel { Map generation = MiscUtils.castToMap(arguments.get("generation"), true); ModelGeneration modelGeneration = null; if (generation != null) { - modelGeneration = new ModelGeneration(Key.of(modelPath), generation); + modelGeneration = ModelGeneration.of(Key.of(modelPath), generation); } if (arguments.containsKey("tints")) { List tints = new ArrayList<>(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/SpecialItemModel.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/SpecialItemModel.java index ccfa2e026..50052ce85 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/SpecialItemModel.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/SpecialItemModel.java @@ -13,7 +13,6 @@ import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.Map; -import java.util.Objects; public class SpecialItemModel implements ItemModel { public static final Factory FACTORY = new Factory(); @@ -69,7 +68,7 @@ public class SpecialItemModel implements ItemModel { Map generation = MiscUtils.castToMap(arguments.get("generation"), true); ModelGeneration modelGeneration = null; if (generation != null) { - modelGeneration = new ModelGeneration(Key.of(base), generation); + modelGeneration = ModelGeneration.of(Key.of(base), generation); } Map model = MiscUtils.castToMap(arguments.get("model"), false); return new SpecialItemModel(SpecialModels.fromMap(model), base, modelGeneration); diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/AbstractModelGenerator.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/AbstractModelGenerator.java index e34e9f374..acc0d0c08 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/AbstractModelGenerator.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/AbstractModelGenerator.java @@ -38,9 +38,12 @@ public abstract class AbstractModelGenerator implements ModelGenerator { if (!ResourceLocation.isValid(model.parentModelPath())) { throw new LocalizedResourceConfigException("warning.config.model.generation.parent.invalid", model.parentModelPath()); } - for (Map.Entry texture : model.texturesOverride().entrySet()) { - if (!ResourceLocation.isValid(texture.getValue())) { - throw new LocalizedResourceConfigException("warning.config.model.generation.texture.invalid", texture.getKey(), texture.getValue()); + Map textures = model.texturesOverride(); + if (textures != null) { + for (Map.Entry texture : textures.entrySet()) { + if (!ResourceLocation.isValid(texture.getValue())) { + throw new LocalizedResourceConfigException("warning.config.model.generation.texture.invalid", texture.getKey(), texture.getValue()); + } } } this.modelsToGenerate.put(model.path(), model); diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/GuiLight.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/GuiLight.java new file mode 100644 index 000000000..0977aa82a --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/GuiLight.java @@ -0,0 +1,5 @@ +package net.momirealms.craftengine.core.pack.model.generation; + +public enum GuiLight { + FRONT, SIDE +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/ModelGeneration.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/ModelGeneration.java index 086d8c6d5..883d89196 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/ModelGeneration.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/ModelGeneration.java @@ -1,44 +1,107 @@ package net.momirealms.craftengine.core.pack.model.generation; +import com.google.gson.JsonArray; import com.google.gson.JsonObject; +import net.momirealms.craftengine.core.pack.model.generation.display.DisplayMeta; +import net.momirealms.craftengine.core.pack.model.generation.display.DisplayPosition; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; +import net.momirealms.craftengine.core.util.EnumUtils; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.joml.Vector3f; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Objects; +import java.util.*; +import java.util.function.BiConsumer; +import java.util.function.Supplier; -public class ModelGeneration { +public class ModelGeneration implements Supplier { + private static final Map> BUILDER_FUNCTIONS = new HashMap<>(); + static { + BUILDER_FUNCTIONS.put("textures", (b, data) -> { + Map texturesMap = MiscUtils.castToMap(data, false); + Map texturesOverride = new LinkedHashMap<>(); + for (Map.Entry entry : texturesMap.entrySet()) { + if (entry.getValue() instanceof String p) { + texturesOverride.put(entry.getKey(), p); + } + } + b.texturesOverride(texturesOverride); + }); + BUILDER_FUNCTIONS.put("display", (b, data) -> { + Map displayMap = MiscUtils.castToMap(data, false); + Map displays = new EnumMap<>(DisplayPosition.class); + for (Map.Entry entry : displayMap.entrySet()) { + try { + DisplayPosition displayPosition = DisplayPosition.valueOf(entry.getKey().toUpperCase(Locale.ENGLISH)); + if (entry.getValue() instanceof Map metaMap) { + displays.put(displayPosition, DisplayMeta.fromMap(MiscUtils.castToMap(metaMap, false))); + } + } catch (IllegalArgumentException e) { + throw new LocalizedResourceConfigException("warning.config.model.generation.invalid_display_position", e, entry.getKey(), EnumUtils.toString(DisplayPosition.values())); + } + } + b.displays(displays); + }); + BUILDER_FUNCTIONS.put("gui-light", (b, data) -> { + String guiLightStr = String.valueOf(data); + try { + GuiLight guiLight = GuiLight.valueOf(guiLightStr.toUpperCase(Locale.ENGLISH)); + b.guiLight(guiLight); + } catch (IllegalArgumentException e) { + throw new LocalizedResourceConfigException("warning.config.model.generation.invalid_gui_light", e, guiLightStr, EnumUtils.toString(GuiLight.values())); + } + }); + BUILDER_FUNCTIONS.put("ambient-occlusion", (b, data) -> { + b.ambientOcclusion((boolean) data); + }); + BUILDER_FUNCTIONS.put("parent", (b, data) -> { + String parentModelPath = data.toString(); + b.parentModelPath(parentModelPath); + }); + } + + @NotNull private final Key path; + @NotNull private final String parentModelPath; + @Nullable private final Map texturesOverride; + @Nullable + private final Map displays; + @Nullable + private final GuiLight guiLight; + @Nullable + private final Boolean ambientOcclusion; + @Nullable + private JsonObject cachedModel; - public ModelGeneration(Key path, String parentModelPath, Map texturesOverride) { + public ModelGeneration(@NotNull Key path, + @NotNull String parentModelPath, + @Nullable Map texturesOverride, + @Nullable Map displays, + @Nullable GuiLight guiLight, + @Nullable Boolean ambientOcclusion) { this.path = path; this.parentModelPath = parentModelPath; this.texturesOverride = texturesOverride; + this.displays = displays; + this.guiLight = guiLight; + this.ambientOcclusion = ambientOcclusion; } - public ModelGeneration(Key path, Map map) { - this.path = path; - Object parent = map.get("parent"); - if (parent == null) { - throw new LocalizedResourceConfigException("warning.config.model.generation.missing_parent"); - } - this.parentModelPath = parent.toString(); - Map texturesMap = MiscUtils.castToMap(map.get("textures"), true); - if (texturesMap != null) { - this.texturesOverride = new LinkedHashMap<>(); - for (Map.Entry entry : texturesMap.entrySet()) { - if (entry.getValue() instanceof String p) { - this.texturesOverride.put(entry.getKey(), p); - } - } - } else { - this.texturesOverride = Collections.emptyMap(); + public static ModelGeneration of(Key path, Map map) { + Builder builder = builder().path(path); + for (Map.Entry entry : map.entrySet()) { + Optional.ofNullable(BUILDER_FUNCTIONS.get(entry.getKey())).ifPresent(it -> it.accept(builder, entry.getValue())); } + return builder.build(); + } + + @Nullable + public Map texturesOverride() { + return texturesOverride; } public Key path() { @@ -49,36 +112,137 @@ public class ModelGeneration { return parentModelPath; } - public Map texturesOverride() { - return texturesOverride; + @Nullable + public Map displays() { + return displays; } - public JsonObject getJson() { + @Nullable + public GuiLight guiLight() { + return guiLight; + } + + @Nullable + public Boolean ambientOcclusion() { + return ambientOcclusion; + } + + @Override + public JsonObject get() { + if (this.cachedModel == null) { + this.cachedModel = this.getCachedModel(); + } + return this.cachedModel; + } + + private JsonObject getCachedModel() { JsonObject model = new JsonObject(); - model.addProperty("parent", parentModelPath); - if (this.texturesOverride != null && !this.texturesOverride.isEmpty()) { + model.addProperty("parent", this.parentModelPath); + if (this.texturesOverride != null) { JsonObject textures = new JsonObject(); for (Map.Entry entry : this.texturesOverride.entrySet()) { textures.addProperty(entry.getKey(), entry.getValue()); } model.add("textures", textures); } + if (this.displays != null) { + JsonObject displays = new JsonObject(); + for (Map.Entry entry : this.displays.entrySet()) { + JsonObject displayMetadata = new JsonObject(); + DisplayMeta meta = entry.getValue(); + if (meta.rotation() != null) + displayMetadata.add("rotation", vectorToJsonArray(meta.rotation())); + if (meta.translation() != null) + displayMetadata.add("translation", vectorToJsonArray(meta.translation())); + if (meta.scale() != null) + displayMetadata.add("scale", vectorToJsonArray(meta.scale())); + displays.add(entry.getKey().name().toLowerCase(Locale.ENGLISH), displayMetadata); + } + model.add("display", displays); + } + if (this.guiLight != null) { + model.addProperty("gui_light", this.guiLight.name().toLowerCase(Locale.ENGLISH)); + } return model; } + private JsonArray vectorToJsonArray(Vector3f vector) { + JsonArray array = new JsonArray(); + array.add(vector.x()); + array.add(vector.y()); + array.add(vector.z()); + return array; + } + @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ModelGeneration that = (ModelGeneration) o; - return this.path.equals(that.path) && parentModelPath.equals(that.parentModelPath) && Objects.equals(texturesOverride, that.texturesOverride); + return this.path.equals(that.path) && parentModelPath.equals(that.parentModelPath) && Objects.equals(texturesOverride, that.texturesOverride) + && Objects.equals(displays, that.displays) && Objects.equals(ambientOcclusion, that.ambientOcclusion) && Objects.equals(guiLight, that.guiLight); } @Override public int hashCode() { - int result = path.hashCode(); - result = 31 * result + parentModelPath.hashCode(); - result = 31 * result + texturesOverride.hashCode(); + int result = this.path.hashCode(); + result = 31 * result + this.parentModelPath.hashCode(); return result; } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private Key path; + private String parentModelPath; + @Nullable + private Map texturesOverride; + @Nullable + private Map displays; + @Nullable + private GuiLight guiLight; + @Nullable + private Boolean ambientOcclusion; + + public Builder() {} + + public Builder path(Key key) { + this.path = key; + return this; + } + + public Builder parentModelPath(String parentModelPath) { + this.parentModelPath = parentModelPath; + return this; + } + + public Builder texturesOverride(Map texturesOverride) { + this.texturesOverride = texturesOverride; + return this; + } + + public Builder displays(Map displays) { + this.displays = displays; + return this; + } + + public Builder guiLight(GuiLight guiLight) { + this.guiLight = guiLight; + return this; + } + + public Builder ambientOcclusion(Boolean ambientOcclusion) { + this.ambientOcclusion = ambientOcclusion; + return this; + } + + public ModelGeneration build() { + if (this.parentModelPath == null) { + throw new LocalizedResourceConfigException("warning.config.model.generation.missing_parent"); + } + return new ModelGeneration(Objects.requireNonNull(this.path, "path should be nonnull"), this.parentModelPath, this.texturesOverride, this.displays, this.guiLight, this.ambientOcclusion); + } + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/display/DisplayMeta.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/display/DisplayMeta.java new file mode 100644 index 000000000..31549e547 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/display/DisplayMeta.java @@ -0,0 +1,25 @@ +package net.momirealms.craftengine.core.pack.model.generation.display; + +import net.momirealms.craftengine.core.util.MiscUtils; +import org.joml.Vector3f; + +import java.util.Map; + +public record DisplayMeta(Vector3f rotation, Vector3f translation, Vector3f scale) { + + public static DisplayMeta fromMap(Map map) { + Vector3f rotation = null; + if (map.containsKey("rotation")) { + rotation = MiscUtils.getAsVector3f(map.get("rotation"), "rotation"); + } + Vector3f translation = null; + if (map.containsKey("translation")) { + translation = MiscUtils.getAsVector3f(map.get("translation"), "translation"); + } + Vector3f scale = null; + if (map.containsKey("scale")) { + scale = MiscUtils.getAsVector3f(map.get("scale"), "scale"); + } + return new DisplayMeta(rotation, translation, scale); + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/display/DisplayPosition.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/display/DisplayPosition.java new file mode 100644 index 000000000..0f5f30a3c --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/display/DisplayPosition.java @@ -0,0 +1,12 @@ +package net.momirealms.craftengine.core.pack.model.generation.display; + +public enum DisplayPosition { + THIRDPERSON_RIGHTHAND, + THIRDPERSON_LEFTHAND, + FIRSTPERSON_RIGHTHAND, + FIRSTPERSON_LEFTHAND, + GUI, + HEAD, + GROUND, + FIXED +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/special/ShulkerBoxSpecialModel.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/special/ShulkerBoxSpecialModel.java index 2ba8f374c..917474670 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/special/ShulkerBoxSpecialModel.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/special/ShulkerBoxSpecialModel.java @@ -7,7 +7,6 @@ import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.ResourceConfigUtils; import org.jetbrains.annotations.Nullable; -import java.awt.desktop.OpenFilesEvent; import java.util.Locale; import java.util.Map; import java.util.Optional; diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/GlobalVariableTag.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/GlobalVariableTag.java index 0a7602b0e..257a3a72e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/GlobalVariableTag.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/GlobalVariableTag.java @@ -6,7 +6,6 @@ import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.context.Context; -import net.momirealms.craftengine.core.plugin.locale.TranslationManager; import net.momirealms.craftengine.core.util.AdventureHelper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; From 289cc5028caadc6711ad64b75b6068c50fb848e1 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Sat, 10 May 2025 00:09:38 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=80=E4=BA=9Btint?= =?UTF-8?q?=E5=92=8Ctexture=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../generation/AbstractModelGenerator.java | 6 ++- .../core/pack/model/tint/ConstantTint.java | 4 +- .../pack/model/tint/CustomModelDataTint.java | 4 +- .../pack/model/tint/SimpleDefaultTint.java | 4 +- .../core/pack/model/tint/Tint.java | 6 +-- .../core/pack/model/tint/TintFactory.java | 41 +++++++++++++++---- gradle.properties | 2 +- 7 files changed, 47 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/AbstractModelGenerator.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/AbstractModelGenerator.java index acc0d0c08..d62e049f2 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/AbstractModelGenerator.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/AbstractModelGenerator.java @@ -41,8 +41,10 @@ public abstract class AbstractModelGenerator implements ModelGenerator { Map textures = model.texturesOverride(); if (textures != null) { for (Map.Entry texture : textures.entrySet()) { - if (!ResourceLocation.isValid(texture.getValue())) { - throw new LocalizedResourceConfigException("warning.config.model.generation.texture.invalid", texture.getKey(), texture.getValue()); + if (texture.getValue().charAt(0) != '#') { + if (!ResourceLocation.isValid(texture.getValue())) { + throw new LocalizedResourceConfigException("warning.config.model.generation.texture.invalid", texture.getKey(), texture.getValue()); + } } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/ConstantTint.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/ConstantTint.java index e1b926ae6..54c6d40c2 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/ConstantTint.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/ConstantTint.java @@ -10,9 +10,9 @@ import java.util.Map; public class ConstantTint implements Tint { public static final Factory FACTORY = new Factory(); - private final Either> value; + private final Either> value; - public ConstantTint(Either> value) { + public ConstantTint(Either> value) { this.value = value; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/CustomModelDataTint.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/CustomModelDataTint.java index c76be9f9e..0ed576384 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/CustomModelDataTint.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/CustomModelDataTint.java @@ -10,10 +10,10 @@ import java.util.Map; public class CustomModelDataTint implements Tint { public static final Factory FACTORY = new Factory(); - private final Either> value; + private final Either> value; private final int index; - public CustomModelDataTint(Either> value, int index) { + public CustomModelDataTint(Either> value, int index) { this.index = index; this.value = value; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/SimpleDefaultTint.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/SimpleDefaultTint.java index a08c0daec..a543bcfe9 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/SimpleDefaultTint.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/SimpleDefaultTint.java @@ -9,10 +9,10 @@ import java.util.Map; public class SimpleDefaultTint implements Tint { public static final Factory FACTORY = new Factory(); - private final Either> value; + private final Either> value; private final Key type; - public SimpleDefaultTint(Either> value, Key type) { + public SimpleDefaultTint(Either> value, Key type) { this.value = value; this.type = type; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/Tint.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/Tint.java index 364145257..b0be23502 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/Tint.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/Tint.java @@ -12,16 +12,16 @@ public interface Tint extends Supplier { Key type(); - default void applyAnyTint(JsonObject json, Either> value, String key) { + default void applyAnyTint(JsonObject json, Either> value, String key) { if (value.primary().isPresent()) { json.addProperty(key, value.primary().get()); } else { - List list = value.fallback().get(); + List list = value.fallback().get(); if (list.size() != 3) { throw new RuntimeException("Invalid tint value list size: " + list.size() + " which is expected to be 3"); } JsonArray array = new JsonArray(); - for (int i : list) { + for (float i : list) { array.add(i); } json.add(key, array); diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/TintFactory.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/TintFactory.java index ee595ad49..e0fbd1947 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/TintFactory.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/tint/TintFactory.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.core.pack.model.tint; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; +import net.momirealms.craftengine.core.util.MiscUtils; import org.incendo.cloud.type.Either; import java.util.ArrayList; @@ -11,27 +12,51 @@ public interface TintFactory { Tint create(Map arguments); - default Either> parseTintValue(Object value) { + default Either> parseTintValue(Object value) { if (value instanceof Number i) { return Either.ofPrimary(i.intValue()); } else if (value instanceof List list) { if (list.size() == 3) { - List intList = new ArrayList<>(); - for (Object o : list) { - intList.add(Integer.parseInt(o.toString())); + List strList = MiscUtils.getAsStringList(list); + boolean hasDot = false; + for (String str : strList) { + if (str.contains(".")) { + hasDot = true; + break; + } } - return Either.ofFallback(intList); + List fList = new ArrayList<>(); + for (String str : strList) { + if (hasDot) { + fList.add(Float.parseFloat(str)); + } else { + fList.add(convertToFloat(Integer.parseInt(str))); + } + } + return Either.ofFallback(fList); } } else if (value instanceof String s) { String[] split = s.split(","); if (split.length == 3) { - List intList = new ArrayList<>(); + List fList = new ArrayList<>(); + boolean hasDot = s.contains("."); for (String string : split) { - intList.add(Integer.parseInt(string)); + if (hasDot) { + fList.add(Float.parseFloat(string)); + } else { + fList.add(convertToFloat(Integer.parseInt(string))); + } } - return Either.ofFallback(intList); + return Either.ofFallback(fList); } } throw new LocalizedResourceConfigException("warning.config.item.model.tint.invalid_value", value.toString()); } + + static float convertToFloat(int value) { + if (value < 0 || value > 255) { + throw new IllegalArgumentException("Tint value out of range: " + value + ". Allowed range is [0,255]"); + } + return value / 255.0f; + } } diff --git a/gradle.properties b/gradle.properties index c7950e2ef..ccae7e353 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.53.3 +project_version=0.0.53.4 config_version=32 lang_version=12 project_group=net.momirealms