From e5c01c55cf6800da5a645703cb6522a9aed324c3 Mon Sep 17 00:00:00 2001 From: iqtester Date: Wed, 23 Jul 2025 12:49:38 -0400 Subject: [PATCH 1/2] Add DoubleHighBlockItemBehavior --- .../item/behavior/BlockItemBehavior.java | 6 +- .../item/behavior/BukkitItemBehaviors.java | 2 + .../behavior/DoubleHighBlockItemBehavior.java | 62 +++++++++++++++++++ .../plugin/reflection/minecraft/MBlocks.java | 4 ++ .../default/configuration/palm_tree.yml | 2 +- .../src/main/resources/translations/en.yml | 1 + .../src/main/resources/translations/zh_cn.yml | 1 + 7 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/DoubleHighBlockItemBehavior.java diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BlockItemBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BlockItemBehavior.java index affec07c6..0fda1036a 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BlockItemBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BlockItemBehavior.java @@ -126,7 +126,7 @@ public class BlockItemBehavior extends BlockBoundItemBehavior { // it's just world + pos BlockState previousState = bukkitBlock.getState(); // place custom block - CraftEngineBlocks.place(placeLocation, blockStateToPlace, UpdateOption.UPDATE_ALL_IMMEDIATE, false); + placeBlock(placeLocation, blockStateToPlace); if (player != null) { // call bukkit event @@ -215,6 +215,10 @@ public class BlockItemBehavior extends BlockBoundItemBehavior { } } + protected boolean placeBlock(Location location, ImmutableBlockState blockState) { + return CraftEngineBlocks.place(location, blockState, UpdateOption.UPDATE_ALL_IMMEDIATE, false); + } + @Override public Key block() { return this.blockId; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BukkitItemBehaviors.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BukkitItemBehaviors.java index 51a030ce8..79292cfda 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BukkitItemBehaviors.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BukkitItemBehaviors.java @@ -11,6 +11,7 @@ public class BukkitItemBehaviors extends ItemBehaviors { public static final Key FLINT_AND_STEEL_ITEM = Key.from("craftengine:flint_and_steel_item"); public static final Key COMPOSTABLE_ITEM = Key.from("craftengine:compostable_item"); public static final Key AXE_ITEM = Key.from("craftengine:axe_item"); + public static final Key DOUBLE_HIGH_BLOCK_ITEM = Key.from("craftengine:double_high_block_item"); public static void init() { register(EMPTY, EmptyItemBehavior.FACTORY); @@ -20,5 +21,6 @@ public class BukkitItemBehaviors extends ItemBehaviors { register(FLINT_AND_STEEL_ITEM, FlintAndSteelItemBehavior.FACTORY); register(COMPOSTABLE_ITEM, CompostableItemBehavior.FACTORY); register(AXE_ITEM, AxeItemBehavior.FACTORY); + register(DOUBLE_HIGH_BLOCK_ITEM, DoubleHighBlockItemBehavior.FACTORY); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/DoubleHighBlockItemBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/DoubleHighBlockItemBehavior.java new file mode 100644 index 000000000..d89aecabb --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/DoubleHighBlockItemBehavior.java @@ -0,0 +1,62 @@ +package net.momirealms.craftengine.bukkit.item.behavior; + +import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; +import net.momirealms.craftengine.bukkit.nms.FastNMS; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks; +import net.momirealms.craftengine.core.block.ImmutableBlockState; +import net.momirealms.craftengine.core.block.UpdateOption; +import net.momirealms.craftengine.core.item.behavior.ItemBehavior; +import net.momirealms.craftengine.core.item.behavior.ItemBehaviorFactory; +import net.momirealms.craftengine.core.pack.Pack; +import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.MiscUtils; +import org.bukkit.Location; +import org.bukkit.Material; + +import java.nio.file.Path; +import java.util.Map; + +public class DoubleHighBlockItemBehavior extends BlockItemBehavior { + public static final Factory FACTORY = new Factory(); + + public DoubleHighBlockItemBehavior(Key blockId) { + super(blockId); + } + + @Override + protected boolean placeBlock(Location location, ImmutableBlockState blockState) { + Object worldServer = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(location.getWorld()); + Object blockPos = FastNMS.INSTANCE.constructor$BlockPos(location.getBlockX(), location.getBlockY() + 1, location.getBlockZ()); + UpdateOption option = UpdateOption.builder().updateNeighbors().updateClients().updateImmediate().updateKnownShape().build(); + Object stateToPlace; + if (location.getWorld().getBlockAt(location.getBlockX(), location.getBlockY() + 1, location.getBlockZ()).getType() == Material.WATER) { + stateToPlace = MBlocks.WATER$defaultState; + } else { + stateToPlace = MBlocks.AIR$defaultState; + } + FastNMS.INSTANCE.method$LevelWriter$setBlock(worldServer, blockPos, stateToPlace, option.flags()); + return super.placeBlock(location, blockState); + } + + public static class Factory implements ItemBehaviorFactory { + @Override + public ItemBehavior create(Pack pack, Path path, Key key, Map arguments) { + Object id = arguments.get("block"); + if (id == null) { + throw new LocalizedResourceConfigException("warning.config.item.behavior.double_high.missing_block", new IllegalArgumentException("Missing required parameter 'block' for double_high_block_item behavior")); + } + if (id instanceof Map map) { + if (map.containsKey(key.toString())) { + // 防呆 + BukkitBlockManager.instance().parser().parseSection(pack, path, key, MiscUtils.castToMap(map.get(key.toString()), false)); + } else { + BukkitBlockManager.instance().parser().parseSection(pack, path, key, MiscUtils.castToMap(map, false)); + } + return new DoubleHighBlockItemBehavior(key); + } else { + return new DoubleHighBlockItemBehavior(Key.of(id.toString())); + } + } + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MBlocks.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MBlocks.java index 34d2f0e65..5255de607 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MBlocks.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MBlocks.java @@ -18,6 +18,8 @@ public final class MBlocks { public static final Object SHULKER_BOX; public static final Object COMPOSTER; public static final Object SNOW; + public static final Object WATER; + public static final Object WATER$defaultState; private static Object getById(String id) { Object rl = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", id); @@ -37,5 +39,7 @@ public final class MBlocks { SHULKER_BOX = getById("shulker_box"); COMPOSTER = getById("composter"); SNOW = getById("snow"); + WATER = getById("water"); + WATER$defaultState = FastNMS.INSTANCE.method$Block$defaultState(WATER); } } diff --git a/common-files/src/main/resources/resources/default/configuration/palm_tree.yml b/common-files/src/main/resources/resources/default/configuration/palm_tree.yml index bd0b2d3ac..a47b29498 100644 --- a/common-files/src/main/resources/resources/default/configuration/palm_tree.yml +++ b/common-files/src/main/resources/resources/default/configuration/palm_tree.yml @@ -348,7 +348,7 @@ items: arguments: path: minecraft:item/custom/palm_door behavior: - type: block_item + type: double_high_block_item block: behavior: type: door_block diff --git a/common-files/src/main/resources/translations/en.yml b/common-files/src/main/resources/translations/en.yml index 375cfd1f0..3134565f4 100644 --- a/common-files/src/main/resources/translations/en.yml +++ b/common-files/src/main/resources/translations/en.yml @@ -187,6 +187,7 @@ warning.config.item.behavior.invalid_type: "Issue found in file warning.config.item.behavior.block.missing_block: "Issue found in file - The item '' is missing the required 'block' argument for 'block_item' behavior." warning.config.item.behavior.furniture.missing_furniture: "Issue found in file - The item '' is missing the required 'furniture' argument for 'furniture_item' behavior." warning.config.item.behavior.liquid_collision.missing_block: "Issue found in file - The item '' is missing the required 'block' argument for 'liquid_collision_block_item' behavior." +warning.config.item.behavior.double_high.missing_block: "Issue found in file - The item '' is missing the required 'block' argument for 'double_high_block_item' behavior." warning.config.item.legacy_model.missing_path: "Issue found in file - The item '' is missing the require 'path' argument for legacy-model." warning.config.item.legacy_model.overrides.missing_path: "Issue found in file - The item '' is missing the require 'path' argument for legacy-model overrides." warning.config.item.legacy_model.overrides.missing_predicate: "Issue found in file - The item '' is missing the require 'predicate' argument for legacy-model overrides." diff --git a/common-files/src/main/resources/translations/zh_cn.yml b/common-files/src/main/resources/translations/zh_cn.yml index 91bfbf70c..8832c01d1 100644 --- a/common-files/src/main/resources/translations/zh_cn.yml +++ b/common-files/src/main/resources/translations/zh_cn.yml @@ -185,6 +185,7 @@ warning.config.item.behavior.invalid_type: "在文件 发现问 warning.config.item.behavior.block.missing_block: "在文件 发现问题 - 物品 '' 的 'block_item' 行为缺少必需的 'block' 参数" warning.config.item.behavior.furniture.missing_furniture: "在文件 发现问题 - 物品 '' 的 'furniture_item' 行为缺少必需的 'furniture' 参数" warning.config.item.behavior.liquid_collision.missing_block: "在文件 发现问题 - 物品 '' 的 'liquid_collision_block_item' 行为缺少必需的 'block' 参数" +warning.config.item.behavior.double_high.missing_block: "在文件 发现问题 - 物品 '' 的 'double_high_block_item' 行为缺少必需的 'block' 参数" warning.config.item.legacy_model.missing_path: "在文件 中发现问题 - 物品 '' 的旧版模型(legacy-model)缺少必需的 'path' 参数" warning.config.item.legacy_model.overrides.missing_path: "在文件 中发现问题 - 物品 '' 的旧版模型覆写规则(overrides)缺少必需的 'path' 参数" warning.config.item.legacy_model.overrides.missing_predicate: "在文件 中发现问题 - 物品 '' 的旧版模型覆写规则(overrides)缺少必需的 'predicate' 参数" From 71d3cfe1f679d5890acd9da694f08598b5b23c32 Mon Sep 17 00:00:00 2001 From: iqtester Date: Thu, 24 Jul 2025 10:44:32 -0400 Subject: [PATCH 2/2] check fluid through NMS --- .../item/behavior/DoubleHighBlockItemBehavior.java | 14 +++++--------- .../plugin/reflection/minecraft/MBlocks.java | 4 ---- .../plugin/reflection/minecraft/MFluids.java | 2 ++ 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/DoubleHighBlockItemBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/DoubleHighBlockItemBehavior.java index d89aecabb..fc8c6cb8c 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/DoubleHighBlockItemBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/DoubleHighBlockItemBehavior.java @@ -3,6 +3,7 @@ package net.momirealms.craftengine.bukkit.item.behavior; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MFluids; import net.momirealms.craftengine.core.block.ImmutableBlockState; import net.momirealms.craftengine.core.block.UpdateOption; import net.momirealms.craftengine.core.item.behavior.ItemBehavior; @@ -12,7 +13,6 @@ import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigExce import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; import org.bukkit.Location; -import org.bukkit.Material; import java.nio.file.Path; import java.util.Map; @@ -26,16 +26,12 @@ public class DoubleHighBlockItemBehavior extends BlockItemBehavior { @Override protected boolean placeBlock(Location location, ImmutableBlockState blockState) { - Object worldServer = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(location.getWorld()); + Object level = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(location.getWorld()); Object blockPos = FastNMS.INSTANCE.constructor$BlockPos(location.getBlockX(), location.getBlockY() + 1, location.getBlockZ()); UpdateOption option = UpdateOption.builder().updateNeighbors().updateClients().updateImmediate().updateKnownShape().build(); - Object stateToPlace; - if (location.getWorld().getBlockAt(location.getBlockX(), location.getBlockY() + 1, location.getBlockZ()).getType() == Material.WATER) { - stateToPlace = MBlocks.WATER$defaultState; - } else { - stateToPlace = MBlocks.AIR$defaultState; - } - FastNMS.INSTANCE.method$LevelWriter$setBlock(worldServer, blockPos, stateToPlace, option.flags()); + Object fluidData = FastNMS.INSTANCE.method$BlockGetter$getFluidState(level, blockPos); + Object stateToPlace = fluidData == MFluids.WATER$defaultState ? MFluids.WATER$defaultState : MBlocks.AIR$defaultState; + FastNMS.INSTANCE.method$LevelWriter$setBlock(level, blockPos, stateToPlace, option.flags()); return super.placeBlock(location, blockState); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MBlocks.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MBlocks.java index 5255de607..34d2f0e65 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MBlocks.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MBlocks.java @@ -18,8 +18,6 @@ public final class MBlocks { public static final Object SHULKER_BOX; public static final Object COMPOSTER; public static final Object SNOW; - public static final Object WATER; - public static final Object WATER$defaultState; private static Object getById(String id) { Object rl = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", id); @@ -39,7 +37,5 @@ public final class MBlocks { SHULKER_BOX = getById("shulker_box"); COMPOSTER = getById("composter"); SNOW = getById("snow"); - WATER = getById("water"); - WATER$defaultState = FastNMS.INSTANCE.method$Block$defaultState(WATER); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MFluids.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MFluids.java index a03660080..414d2472d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MFluids.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MFluids.java @@ -7,6 +7,7 @@ public final class MFluids { private MFluids() {} public static final Object WATER; + public static final Object WATER$defaultState; public static final Object FLOWING_WATER; public static final Object LAVA; public static final Object FLOWING_LAVA; @@ -21,6 +22,7 @@ public final class MFluids { static { try { WATER = getById("water"); + WATER$defaultState = CoreReflections.method$Fluid$defaultFluidState.invoke(WATER); FLOWING_WATER = getById("flowing_water"); LAVA = getById("lava"); FLOWING_LAVA = getById("flowing_lava");