Doc ID: SIRC-123

CraftEngine API 知识文档

CraftEngine 是一个用于 Minecraft 服务器的自定义内容创建框架,支持自定义物品、方块、家具、配方等。本文档重点介绍 API 用法、包名和变量占位符

Overview

CraftEngine API 文档

概述

CraftEngine 是一个用于 Minecraft 服务器的自定义内容创建框架,支持自定义物品、方块、家具、配方等。本文档重点介绍 API 用法、包名和变量占位符。

核心包结构

主要包名

  • net.momirealms.craftengine.core.plugin – 核心插件类和单例访问
  • net.momirealms.craftengine.core.item – 物品系统
  • net.momirealms.craftengine.core.block – 方块系统
  • net.momirealms.craftengine.core.entity.furniture – 家具系统
  • net.momirealms.craftengine.core.pack – 资源包系统
  • net.momirealms.craftengine.core.plugin.context – 事件上下文系统
  • net.momirealms.craftengine.bukkit.api – Bukkit 适配器
  • net.momirealms.craftengine.bukkit.item.listener – 物品事件监听器

API 集成指南

获取 CraftEngine 实例

import net.momirealms.craftengine.core.plugin.CraftEngine;

// 单例模式访问
CraftEngine engine = CraftEngine.instance();

// 检查初始化状态
if (engine.isReloading()) {
    // 正在重载
}
if (engine.isInitializing()) {
    // 首次初始化
}

管理器访问

CraftEngine 提供以下管理器:

管理器 访问方法 用途
ItemManager itemManager() 自定义物品注册、行为、模型生成
BlockManager blockManager() 自定义方块注册、行为、状态分配
RecipeManager recipeManager() 自定义配方注册、事件处理
FurnitureManager furnitureManager() 多实体家具结构
PackManager packManager() 资源包生成、解析器注册
NetworkManager networkManager() 数据包注入、玩家状态跟踪
TranslationManager translationManager() 国际化、本地化管理
WorldManager worldManager() 区块存储、方块持久化
TemplateManager templateManager() 配置模板、可重用模式
GlobalVariableManager globalVariableManager() 全局配置变量
CompatibilityManager compatibilityManager() 外部插件集成
ProjectileManager projectileManager() 自定义抛射物实体

类型参数

管理器使用泛型类型参数:

ItemManager<?> itemManager = engine.itemManager();
RecipeManager<?> recipeManager = engine.recipeManager();
// 类型参数 T 表示平台特定的物品/配方类型

物品系统 API

查询自定义物品

ItemManager<?> itemManager = CraftEngine.instance().itemManager();

// 通过 ID 获取自定义物品
Optional<CustomItem> customItem = itemManager.getItem("mypack:custom_sword");
if (customItem.isPresent()) {
    CustomItem item = customItem.get();
    String displayName = item.displayName();
    ItemSettings settings = item.settings();
}

// 遍历所有自定义物品
Collection<CustomItem> allItems = itemManager.getAllItems();

物品配置结构

items:
  my_namespace:custom_sword:
    material: diamond_sword
    custom-model-data: 1000
    item-model: "my_namespace:custom_sword"
    data:
      max_stack_size: 1
      rarity: "rare"
      custom_name: "<rainbow>Legendary Sword"

物品行为类型

行为类型 描述 必需参数
block_item 放置自定义方块 block
wall_block_item 在墙上放置方块 block
ceiling_block_item 在天花板放置方块 block
furniture_item 放置家具 furniture
consumable 可食用/饮用 consume-time
throwable 投掷抛射物 projectile-item

物品设置

items:
  example:
    settings:
      # 堆叠属性
      max-stack-size: 64
      # 耐久度
      durability: 1000
      max-durability: 1000
      unbreakable: false
      # 燃料
      fuel-time: 200
      # 装备
      equipment:
        asset-id: "namespace:armor_set"
        slot: "chest"
      # 食物
      food:
        nutrition: 4
        saturation: 0.6
        can-always-eat: false

方块系统 API

查询自定义方块

BlockManager blockManager = CraftEngine.instance().blockManager();
String blockId = "mypack:custom_ore";

Optional<CustomBlock> customBlock = blockManager.getBlock(blockId);
if (customBlock.isPresent()) {
    int visualState = blockManager.getBlockState(blockId);
}

方块配置结构

blocks:
  my_namespace:custom_ore:
    block-state: "minecraft:note_block[instrument=harp,note=0]"
    properties:
      facing:
        type: "enum"
        values: ["north", "south", "east", "west"]
      lit:
        type: "boolean"
        values: [true, false]
    variants:
      "facing=north,lit=false":
        block-state: "minecraft:note_block[instrument=harp,note=0]"
        model: "namespace:block/ore_unlit_north"

方块行为类型

行为 用途 关键参数
crop_block 种植作物 max-age, seeds, crop
door_block 门机制 open-sound, close-sound
trapdoor_block 活板门机制 open-sound, close-sound
falling_block 重力影响 damage-amount
leaves_block 树叶腐烂 distance
strippable_block 斧头剥离 stripped-block
simple_storage_block 库存容器 rows, title
seat_block 玩家座位 height

方块设置

blocks:
  example:
    settings:
      # 物理属性
      hardness: 3.0
      resistance: 3.0
      friction: 0.6
      speed-factor: 1.0
      jump-factor: 1.0
      # 光照
      luminance: 15
      # 行为标志
      replaceable: false
      burnable: true
      # 红石
      is-redstone-conductor: true
      # 声音
      sounds:
        break: "block.stone.break"
        step: "block.stone.step"

家具系统 API

家具配置结构

furniture:
  my_namespace:custom_chair:
    item: "namespace:chair_item"
    variants:
      "0":  # 南方向
        elements:
          - type: "item_display"
            item: "namespace:chair_model"
            translation: [0, 0, 0]
            scale: [1, 1, 1]
            rotation: [0, 0, 0, 1]
          - type: "interaction"
            width: 1.0
            height: 1.0
            translation: [0, 0, 0]

家具元素类型

元素类型 使用的实体 用途
item_display ItemDisplay 3D 物品模型
block_display BlockDisplay 方块模型
text_display TextDisplay 文本标签
interaction Interaction 点击检测
item Item 掉落物品实体
armor_stand ArmorStand 传统模型

家具行为

furniture:
  interactive_furniture:
    behaviors:
      - type: "craftengine:seat"
        height: 0.5
      - type: "craftengine:storage"
        rows: 3
        title: "<blue>Furniture Storage"
      - type: "craftengine:particle"
        particle: "flame"
        offset: [0, 1, 0]
        interval: 10

事件系统 API

自定义事件

主要自定义事件是 CustomBlockInteractEvent,在玩家与自定义方块交互时触发。

事件属性

属性 类型 描述
player Player 执行交互的玩家
location Location 自定义方块的位置
interactionPoint Location 玩家点击的精确点(可为空)
blockState ImmutableBlockState 正在交互的自定义方块状态
block Block Bukkit Block 对象
blockFace BlockFace 被点击的方块面
hand EquipmentSlot 使用的手(HAND 或 OFF_HAND)
action Action RIGHT_CLICK 或 LEFT_CLICK
item ItemStack 玩家手中的物品(可为空)

事件监听示例

import net.momirealms.craftengine.bukkit.api.event.CustomBlockInteractEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;

public class CustomBlockListener implements Listener {
    @EventHandler(priority = EventPriority.NORMAL)
    public void onCustomBlockInteract(CustomBlockInteractEvent event) {
        // 提取事件数据
        Player player = event.getPlayer();
        ImmutableBlockState blockState = event.getBlockState();
        CustomBlock customBlock = blockState.owner().value();
        
        // 按自定义方块ID过滤
        if (customBlock.id().equals(Key.of("mynamespace:my_custom_block"))) {
            // 处理右键与左键
            if (event.getAction() == CustomBlockInteractEvent.Action.RIGHT_CLICK) {
                player.sendMessage("You right-clicked my custom block!");
            } else {
                player.sendMessage("You left-clicked my custom block!");
            }
            
            // 取消以阻止 CraftEngine 的默认行为
            event.setCancelled(true);
        }
    }
}

事件触发器

CraftEngine 使用 EventTrigger 枚举来分类交互类型:

触发器 代码符号 触发者 示例位置
RIGHT_CLICK EventTrigger.RIGHT_CLICK 玩家右键点击物品或方块/实体 ItemEventListener.java 106-402
LEFT_CLICK EventTrigger.LEFT_CLICK 玩家左键点击物品或方块 ItemEventListener.java 183-361
CONSUME EventTrigger.CONSUME 玩家完成吃/喝物品 ItemEventListener.java 444
PICK_UP EventTrigger.PICK_UP 玩家从地面捡起物品实体 ItemEventListener.java 608

事件上下文系统

CraftEngine 使用类型安全的上下文系统,围绕 ContextHolderPlayerOptionalContextDirectContextParameters 构建。

上下文参数参考

参数键 值类型 必需 使用示例位置
DirectContextParameters.BLOCK BukkitExistingBlock 是(方块交互) ItemEventListener.java 175
DirectContextParameters.CUSTOM_BLOCK_STATE ImmutableBlockState ItemEventListener.java 176-334
DirectContextParameters.ITEM_IN_HAND Item ItemEventListener.java 99-440
DirectContextParameters.HAND InteractionHand ItemEventListener.java 100-442
DirectContextParameters.EVENT Cancellable 是(可取消事件) ItemEventListener.java 101-607
DirectContextParameters.POSITION WorldPosition ItemEventListener.java 103-606
DirectContextParameters.ENTITY BukkitEntity ItemEventListener.java 102-605

上下文构建模式

// 方块交互上下文
PlayerOptionalContext context = PlayerOptionalContext.of(serverPlayer, ContextHolder.builder()
    .withParameter(DirectContextParameters.BLOCK, new BukkitExistingBlock(block))
    .withParameter(DirectContextParameters.CUSTOM_BLOCK_STATE, immutableBlockState)
    .withParameter(DirectContextParameters.HAND, hand)
    .withParameter(DirectContextParameters.EVENT, dummy)
    .withParameter(DirectContextParameters.POSITION, LocationUtils.toWorldPosition(block.getLocation()))
    .withOptionalParameter(DirectContextParameters.ITEM_IN_HAND, ItemUtils.isEmpty(itemInHand) ? null : itemInHand)
);

// 物品消耗上下文
PlayerOptionalContext context = PlayerOptionalContext.of(serverPlayer, ContextHolder.builder()
    .withParameter(DirectContextParameters.ITEM_IN_HAND, wrapped)
    .withParameter(DirectContextParameters.EVENT, cancellable)
    .withParameter(DirectContextParameters.HAND, event.getHand() == EquipmentSlot.HAND ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND)
);

自定义解析器注册

ConfigSectionParser 接口

public interface ConfigSectionParser {
    /**
     * 获取此解析器处理的配置部分键
     */
    String getKey();
    
    /**
     * 解析配置部分
     * @param pack 正在加载的资源包
     * @param configSection YAML 部分
     */
    void parse(Pack pack, ConfigurationSection configSection);
}

解析器注册

public class MyPlugin extends JavaPlugin {
    @Override
    public void onLoad() {
        CraftEngine engine = CraftEngine.instance();
        
        // 在 onLoad 阶段注册解析器
        engine.beforeEnableTaskRegistry().addTask(() -> {
            MyCustomParser parser = new MyCustomParser();
            engine.packManager().registerConfigSectionParser(parser);
        });
    }
}

示例:自定义部分解析器

public class CustomWeaponParser implements ConfigSectionParser {
    @Override
    public String getKey() {
        return "custom-weapons"; // YAML 键
    }
    
    @Override
    public void parse(Pack pack, ConfigurationSection section) {
        if (section == null) return;
        
        for (String weaponId : section.getKeys(false)) {
            ConfigurationSection weaponSection = section.getConfigurationSection(weaponId);
            // 解析武器属性
            int damage = weaponSection.getInt("damage", 10);
            double attackSpeed = weaponSection.getDouble("attack-speed", 1.0);
            // 注册武器数据...
            registerWeapon(weaponId, damage, attackSpeed);
        }
    }
}

插件生命周期集成

任务注册系统

CraftEngine 提供两个任务注册器用于精确的生命周期控制:

启用前任务

beforeEnableTaskRegistry() 中注册的任务在 CraftEngine 主初始化之前执行,但在管理器构造之后执行。用于:

  • 注册自定义解析器
  • 注入自定义行为工厂
  • 在加载前修改配置
CraftEngine.instance().beforeEnableTaskRegistry().addTask(() -> {
    // 在 CraftEngine.onPluginEnable() 之前执行
    registerCustomParsers();
    injectCustomBehaviors();
});

启用后任务

afterEnableTaskRegistry() 中注册的任务在 CraftEngine 初始化之后执行,但在资源加载之前执行。用于:

  • 注册外部物品源
  • 设置兼容性桥接
  • 初始化依赖 CraftEngine 管理器的系统
CraftEngine.instance().afterEnableTaskRegistry().addTask(() -> {
    // 在 CraftEngine.onPluginEnable() 之后执行
    // 但在完整资源加载之前
    registerExternalItemSource();
});

变量占位符系统

全局变量

在配置中定义可重用的值:

global-variables:
  DAMAGE_MULTIPLIER: 1.5
  MAX_DURABILITY: 2000

items:
  example:
    durability: ${MAX_DURABILITY}
    data:
      attribute_modifiers:
        - type: "generic.attack_damage"
          amount:
            type: "expression"
            expression: "5 * ${DAMAGE_MULTIPLIER}"

模板系统

模板允许配置重用:

templates:
  common_tool:
    durability: 1000
    max-stack-size: 1
    data:
      attribute_modifiers:
        - type: "generic.attack_speed"
          amount: -2.4
          operation: "add_value"

items:
  sword_1:
    template: "common_tool"
    material: "diamond_sword"
  sword_2:
    template: "common_tool"
    material: "netherite_sword"

条件逻辑

用于动态行为的条件逻辑:

items:
  conditional_item:
    behaviors:
      - type: "craftengine:conditional"
        condition:
          type: "permission"
          permission: "craftengine.vip"
        on-success:
          - type: "craftengine:give_item"
            item: "namespace:reward"
        on-failure:
          - type: "craftengine:message"
            message: "<red>VIP required!"

条件类型

类型 用途 参数
permission 检查权限 permission
string_equals 比较字符串 value1, value2
expression 评估表达式 expression
all_of 逻辑与 terms: […]
any_of 逻辑或 terms: […]
inverted 逻辑非 term: {…}

资源包系统

资源包结构

plugins/CraftEngine/resources/
├── pack.yml                    # 资源包元数据
├── contents/                   # YAML 配置文件
│   ├── items.yml
│   ├── blocks.yml
│   └── furniture.yml
└── assets/                     # 资源包资源
    ├── textures/
    ├── models/
    └── sounds/

资源包元数据格式

# pack.yml
namespace: "mynamespace"
priority: 1

最佳实践

时机考虑

操作 推荐阶段 注册方法
注册自定义解析器 onLoad() beforeEnableTaskRegistry()
注入自定义行为 onLoad() beforeEnableTaskRegistry()
注册外部物品源 onLoad() afterEnableTaskRegistry()
访问管理器 onEnable() 直接访问
查询自定义内容 onEnable() 初始化后检查

错误处理

// 安全的管理器访问
try {
    CraftEngine engine = CraftEngine.instance();
    ItemManager<?> itemManager = engine.itemManager();
    // 使用管理器...
} catch (IllegalStateException e) {
    getLogger().severe("CraftEngine not initialized!");
    getServer().getPluginManager().disablePlugin(this);
}

性能考虑

  • 缓存管理器引用:避免重复的 instance() 调用
  • 使用异步方法:许多管理器通过 scheduler() 支持异步操作
  • 最小化重载钩子:重载操作是资源密集型的
  • 批量查询:使用集合方法(getAllItems())而不是迭代查找

完整集成示例

package com.example.myplugin;

import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.item.ItemManager;
import net.momirealms.craftengine.core.block.BlockManager;
import net.momirealms.craftengine.core.pack.PackManager;
import org.bukkit.plugin.java.JavaPlugin;

public class MyPlugin extends JavaPlugin {
    @Override
    public void onLoad() {
        // 阶段1:获取 CraftEngine 实例
        CraftEngine engine = CraftEngine.instance();
        
        // 阶段2:在 CraftEngine 启用前注册任务
        engine.beforeEnableTaskRegistry().addTask(() -> {
            // 注册自定义解析器
            MyCustomParser parser = new MyCustomParser();
            engine.packManager().registerConfigSectionParser(parser);
            // 注册自定义行为工厂
            registerCustomBehaviors(engine);
        });
        
        // 阶段3:在 CraftEngine 启用后注册任务
        engine.afterEnableTaskRegistry().addTask(() -> {
            // 注册外部集成
            registerExternalItemSources(engine);
        });
    }
    
    @Override
    public void onEnable() {
        CraftEngine engine = CraftEngine.instance();
        
        // 访问管理器
        ItemManager<?> itemManager = engine.itemManager();
        BlockManager blockManager = engine.blockManager();
        
        // 查询自定义物品
        itemManager.getItem("mypack:custom_item").ifPresent(item -> {
            getLogger().info("Found custom item: " + item.id());
        });
        
        // 注册事件监听器
        registerEventListeners();
        // 设置命令
        setupCommands();
    }
    
    @Override
    public void onDisable() {
        // 清理资源
    }
    
    private void registerCustomBehaviors(CraftEngine engine) {
        // 实现...
    }
    
    private void registerExternalItemSources(CraftEngine engine) {
        // 实现...
    }
    
    private void registerEventListeners() {
        // 实现...
    }
    
    private void setupCommands() {
        // 实现...
    }
}

常量参考

BlockKeys 常量

用于事件处理程序中的特定原版方块检查:

  • 功能方块:CRAFTING_TABLE, ANVIL, FURNACE, SMITHING_TABLE, GRINDSTONE, LOOM, ENCHANTING_TABLE, BREWING_STAND
  • 交互方块:NOTE_BLOCK, BELL, LECTERN, JUKEBOX, COMPOSTER, RESPAWN_ANCHOR
  • 红石组件:REPEATER, COMPARATOR, LEVER, DAYLIGHT_DETECTOR, DISPENSER, DROPPER, HOPPER
  • 存储:CHEST, BARREL, ENDER_CHEST, TRAPPED_CHEST, SHULKER_BOX(及颜色变体)

ItemKeys 常量

用于原版物品类型检查:

  • 工具:FLINT_AND_STEEL, SHEARS, BRUSH, BUCKET, WATER_BUCKET, LAVA_BUCKET
  • 特殊物品:BONE_MEAL, ENDER_EYE, SADDLE, GLASS_BOTTLE, COMPASS

EntityTypeKeys 常量

用于实体交互事件:

  • 动物:COW, SHEEP, PIG, CHICKEN, HORSE, DONKEY, LLAMA, CAMEL
  • 水生生物:COD, SALMON, TROPICAL_FISH, PUFFERFISH, DOLPHIN, AXOLOTL
  • 宠物:WOLF, CAT, PARROT, FOX, OCELOT

API 稳定性说明

  • core 模块中的接口被认为是稳定的 API
  • 标记为 @ApiStatus.Experimental 的类可能在版本之间更改
  • beforeEnableTaskRegistry()afterEnableTaskRegistry() 是实验性的
  • 更新 CraftEngine 版本时检查变更日志