PAPER / PURPUR 1.21.X · JAVA 21

AdventureCraftings
中文配置 Wiki

面向服主与配置人员的单页手册。涵盖有序/无序配方、字符矩阵、材料数量、概率产物、多 GUI、配方解锁、延时队列、Vault / AdventureMoney、LuckPerms 权限消耗、PAPI 条件、时段与制作次数限制。

当前版本 3.9.7默认文本格式 &支持 RGB / MiniMessageMySQL + Redis + 文件降级内置配方编辑器

功能总览

配方系统

支持 shaped 有序与 shapeless 无序配方;每个格子可要求多个物品,并可为一次制作设置多个独立概率结果。

多 GUI

guis/*.yml 每个文件就是一个界面。标题、行数、槽位、背景、输出状态、装饰物和打开权限均可独立配置。

前置条件

可组合 Vault、AdventureMoney、权限、权限消费、PAPI 比较、时段和 X 天内次数限制。未配置时默认不限制。

队列与存储

瞬时配方直接产出;延时配方进入 GUI 输出槽。MySQL 保存统计和日志,Redis 同步队列,服务不可用时可降级到文件。

安装与依赖

准备环境
使用 Java 21 和 Paper / Purpur 1.21.x。关闭服务器后把 JAR 放入 plugins/
安装可选前置
按使用功能安装 Vault、经济插件、AdventureMoney、PlaceholderAPI 和 LuckPerms。
首次启动
插件自动生成配置、GUI、配方示例及数据目录。确认控制台出现“已启用”和已加载配方数量。
编辑并重载
修改 YAML 后执行 /craft admin reload。更新 JAR 或依赖时必须完整重启,不建议热卸载插件。

依赖关系

插件是否必需用途
Vault按需启用 vault-cost 或旧 money-cost 时需要,同时还需一个 Vault 经济实现。
AdventureMoney按需使用 MONEYACOINGCOIN 条件与消费。
LuckPerms按需使用 consume-permissions 时,通过官方 API 从玩家移除权限节点。
PlaceholderAPI按需提供 AC 统计变量;使用配方 requirements.papi 时必须安装。
MySQL推荐玩家解锁、合成统计、溯源日志和队列日志。
Redis群组服推荐跨服队列状态、锁与配方版本广播。
提示:没有使用某项条件时,对应前置插件可以不安装。所有配方前置条件默认关闭。

文件结构

plugins/AdventureCrafings/
├─ config.yml                 # 服务端标识、语言、调试开关
├─ settings.yml               # 队列、配方书、原版工作台入口
├─ messages.yml               # 玩家消息
├─ database.yml               # MySQL、Redis、文件降级
├─ guis/
│  ├─ crafting-gui.yml        # 默认 /craft 界面
│  └─ crafting-gui-2.yml      # 可自行复制新增
├─ recipes/
│  ├─ example.yml             # 示例;可拆分任意数量 YAML
│  ├─ weapons.yml
│  └─ materials.yml
├─ imports/                   # /craft editor tools 导入目录;放入待导入 yml
├─ exports/                   # /craft editor tools 导出目录
├─ backups/
│  ├─ recipes-delete/         # 删除配方时的单配方备份
│  └─ recipes-revisions/      # 保存/移动配方前的 revision 备份
└─ data/
   ├─ player-data.yml         # 解锁数据本地副本
   ├─ craft-history.yml       # 时段内/终身制作次数记录
   └─ storage-fallback.yml    # 存储不可用时的日志降级
命名注意:项目展示名常写作 AdventureCraftings;插件内部目录、JAR 与 PAPI 旧兼容标识仍使用历史拼写 AdventureCrafings

加载、拆分与热重载

  • recipes/ 下所有 .yml 会合并加载,配方 ID 不可重复。
  • guis/ 下文件名去掉 .yml 后就是 GUI ID,并统一转为小写。
  • 执行 /craft admin reload 会重新加载主配置、消息、全部 GUI 与配方,并通过 Redis 广播配方版本。
  • 旧根目录 recipes.yml 会迁移到 recipes/legacy.yml;旧 settings.ymlcrafting-gui 会在无 GUI 文件时迁移。
YAML 对缩进敏感,只使用空格,不要使用 Tab。热重载后先观察控制台,任何配方或 GUI 加载失败都会打印对应 ID 和原因。

config.yml

插件级基础设置。

server-id: "lobby"   # 当前子服唯一标识;写入合成和队列日志
language: "zh_CN"   # 预留语言标识;当前玩家文本主要来自 messages.yml
debug: false        # 调试开关;生产服建议 false
路径类型/默认值说明
server-id字符串 / lobby群组服每个子服应使用不同值,例如 lobby、survival-1。
language字符串 / zh_CN语言标识。
debug布尔 / false调试功能总开关。

settings.yml

通用功能开关、队列容量和配方书配置。合成 GUI 已移入 guis/

native-workbench-entry: false  # true:原版工作台匹配到 AC 配方后转入自定义 GUI
queue:
  default-slots: 5            # 所有玩家默认队列槽数量
  maximum-slots: 10           # 队列硬上限,同时受 GUI output-slots 数量限制
recipe-book:
  title: "&8AdventureCrafings · 配方书"  # 配方书标题
  show-only-public: true      # true:仅展示 public: true 的配方
maximum-slots 不会凭空增加 GUI 格子。实际可见数量取配置上限、玩家权限和所有 GUI 最大输出槽数量的共同限制。

database.yml

storage:
  fallback-to-file: true  # MySQL 不可用时写入 data/storage-fallback.yml
  fail-fast: false        # true:MySQL/Redis 按配置启用但连接失败时停用插件
mysql:
  enabled: true           # 是否启用 MySQL
  host: localhost         # 主机或 IP
  port: 3306              # 端口
  database: adventurecrafings # 数据库名(需预先创建)
  username: root          # 用户名
  password: ""            # 密码;含特殊字符时加引号
  pool-size: 10           # HikariCP 最大连接数
redis:
  enabled: true           # 是否启用 Redis
  host: localhost
  port: 6379
  password: ""            # 无密码保持空字符串
  database: 0             # Redis 逻辑库编号
  timeout-ms: 3000        # 连接/操作超时毫秒

存储策略

场景行为
MySQL 正常写入玩家解锁、合成日志、统计与队列日志。
MySQL 失败 + fallback=true日志临时写入本地降级文件,可用 /craft admin sync 后续同步。
Redis 失败使用本机队列存储模式,跨服一致性不可用。
fail-fast=true已启用的 MySQL 或 Redis 任一连接失败,插件主动停用。

messages.yml

所有值均支持 &、RGB/Hex 和 MiniMessage。v3.6.0 起消息前缀使用 prefixes + message-types 统一管理,推荐用 &a[!]&e[!]&c[!] 区分普通提醒、警告与拒绝。

占位符触发场景
prefixes固定三色前缀:info/success、warn、error。
message-types消息键指定某条消息使用哪个前缀。
condition-failed%reason%权限、PAPI、时段、次数等条件失败;具体原因来自 condition-lore.yml。
queue-fail.*队列、扣款、日志写入、前置消耗失败。
notify.*%recipe%Title、ActionBar、BossBar 等制作完成通知。
cmd.*按键不同玩家/管理员指令提示、帮助、状态、同步结果。
recipe-book.*按键不同配方书标题、按钮名称、Lore、详情界面文本。
prefixes:
  info: "&a[!] &r"
  warn: "&e[!] &r"
  error: "&c[!] &r"
default-prefix: info
message-types:
  no-permission: error
  task-created: success
condition-failed: "%reason%" # %reason% 来自 condition-lore.yml → failures
notify:
  ready-title: "&a制作完成"
  ready-actionbar: "&a制作完成:&f%recipe%"

editor-tools:维护工具文案

/craft editor tools 的 GUI 标题、按钮、健康检查展示、聊天输入提示、导入导出反馈都在 messages.yml → editor-tools 下配置。v3.9.7 起这些用户可见文本不再写死在 jar 中。

editor-tools:
  title: "&8Recipe Editor Tools"     # 工具主界面标题
  state:
    none: "<none>"
    public: "&aPUBLIC"
    private: "&cPRIVATE"
    on: "&aON"
    off: "&cOFF"
  buttons:
    search:
      name: "&eSearch"
      lore:
        - "&7Current: &f%query%"
        - "&7Click and type recipe id/name/folder."
    health:
      name: "&cRecipe Health Check"
      lore:
        - "&7List duplicate ids, missing result/material,"
        - "&7invalid material/sound and non-yml files."
  health:
    title: "&8Recipe Health Check"
    issue-line-prefix: "&7"
    issues:
      duplicate-id: "duplicate id %id% in %files%"
      bad-result-material: "%file% -> %id%: invalid result material %value%"
  export:
    success: "&aExported %count% recipe(s) to %path%"
    failed: "&cExport failed: %reason%"
  import:
    empty: "&ePut yml files into %path% first."
    success: "&aImported %count% file(s), recipes reloaded."
    rejected: "&cImport rejected: %reason%"
不要配置化的内容:导入文件名正则、配方 ID 正则、概率和数量范围属于安全逻辑,仍保留在代码内,避免被误配后造成路径遍历、覆盖配置或刷物。

condition-lore.yml

这是 v3.6.0 新增的专用配置文件,用来统一管理所有前置条件的不足提示,以及右键结果物品时显示的满足/不满足 Lore。

优先级:配方内 requirement-lore.met/unmet > condition-lore.yml 统一模板。
区域用途
status.met / status.unmet满足/不满足状态文本,例如 &a[已满足]&c[未满足]
labels.*每种条件的可读名称,支持 %value%
lore.met / lore.unmet右键结果物品查看需求时的统一 Lore 行模板。
failures.*左键制作失败、队列校验失败时展示的具体原因。
status:
  met: "&a[已满足]"
  unmet: "&c[未满足]"
labels:
  vault: "Vault 余额:%value%"
  permission: "权限:%value%"
lore:
  met:
    default: "&7%condition% &a%status%"
  unmet:
    default: "&7%condition% &c%status%"
failures:
  vault-missing: "&cVault 余额不足,需要:&f%amount%"
  permission-missing: "&c缺少权限:&f%permission%"

GUI 文件:guis/*.yml

文件名就是 GUI ID。例如 crafting-gui-2.yml 使用 /craft open crafting-gui-2 打开。默认入口 /craft 固定尝试打开 crafting-gui

完整带注释模板

# 文件名:crafting-gui.yml → GUI ID 为 crafting-gui
open-permission: "adventurecraftings.gui.crafting-gui" # 打开权限;空字符串表示不额外限制
title: "&8AdventureCrafings · 自定义合成" # GUI 标题,支持颜色与 MiniMessage
rows: 6                         # 箱子行数:1-6,每行9格

# 3×3 材料区,必须正好9个有效槽位。GUI 槽位从0开始。
matrix-slots: [10, 11, 12, 19, 20, 21, 28, 29, 30]
result-slot: 24                 # 匹配配方后的可点击预览/制作按钮

# 延时任务与待领取成品显示位置,至少1个、最多10个。
output-slots: [44, 45, 46, 47, 48, 49, 50, 51, 52, 53]

filler:
  enabled: true                # 是否自动填充全部非功能槽
  material: BLACK_STAINED_GLASS_PANE # Bukkit Material 名称
  name: " "                    # 填充物名称;空格可隐藏名称
  lore: []                     # 填充物 Lore

preview:
  use-recipe-item: true        # true:复制配方第一个结果的外观
  material: CRAFTING_TABLE     # false 时使用此材质
  name: "&a%recipe%"           # false 或非空时作为预览名称
  append-lore: true            # true:保留成品 Lore 后追加;false:替换
  lore:
    - "&a点击开始制作"
    - "%time%"
  instant-time: "&7瞬时合成"  # %time% 在0秒配方中替换为此文本
  delayed-time: "&7制作时间:&f%seconds% 秒"

output:
  show-empty: false            # 是否在空队列槽显示占位物品
  empty-material: GRAY_STAINED_GLASS_PANE
  empty-name: "&7空闲制作槽"
  empty-lore: ["&8等待新的制作任务"]
  crafting:                    # 正在计时的队列任务样式
    use-recipe-item: true
    material: CLOCK
    name: "&e%recipe%"
    append-lore: true
    lore: ["&e制作中 · 剩余 %seconds% 秒"]
  ready:                       # 已完成、等待点击领取的样式
    use-recipe-item: true
    material: CHEST
    name: "&a%recipe%"
    append-lore: true
    lore: ["&a✔ 点击领取"]
    glint: true                # 是否显示附魔光效

# 自定义静态装饰物;键名可自定义。与材料/结果/输出槽冲突时功能槽优先。
decorations:
  info:
    slots: [4, 13]
    material: KNOWLEDGE_BOOK
    name: "&6冒险合成说明"
    lore:
      - "&7把材料放入左侧3×3区域"
      - "&7点击右侧成品开始制作"

槽位编号参考

第1行: 0  1  2  3  4  5  6  7  8
第2行: 9 10 11 12 13 14 15 16 17
第3行:18 19 20 21 22 23 24 25 26
第4行:27 28 29 30 31 32 33 34 35
第5行:36 37 38 39 40 41 42 43 44
第6行:45 46 47 48 49 50 51 52 53

创建第二个 GUI

  1. 复制 guis/crafting-gui.ymlguis/crafting-gui-2.yml
  2. 修改 open-permission: "adventurecraftings.gui.crafting-gui-2"
  3. 执行 /craft admin reload
  4. 给玩家权限并使用 /craft open crafting-gui-2
  5. 在配方中加入 crafting-guis: ["crafting-gui-2"] 才能让它只在第二个 GUI 制作。
布局校验:rows 只能为1-6;材料槽必须9个;结果槽不能与材料槽冲突;输出槽会过滤越界和冲突项,过滤后必须至少剩1个。

配方文件与基础字段

每个文件最外层必须是 recipes:。其下键名是全局唯一的配方 ID,仅建议使用小写字母、数字、下划线和连字符。

字段类型/默认说明
display-name字符串 / 配方ID配方书、消息、GUI 和通知使用的展示名称。
public布尔 / true是否属于公开配方;配方书按设置决定是否只展示公开配方。
default-unlocked布尔 / falsetrue 时所有玩家默认解锁,不必写入玩家解锁数据。
typeshapedshaped 有序;shapeless 无序。旧 shapeless: true 兼容。
permission字符串 / 空制作权限;空字符串不限制。它只检查,不消费。
crafting-guis字符串列表允许制作的 GUI ID;省略时为 ["crafting-gui"]["*"] 允许全部 GUI。
craft-time整数 / 0制作秒数。0 为即时产出;大于0进入队列。
matrix3个字符串3×3 字符摆放图,每行必须正好3个字符。
ingredients映射矩阵字符对应的 Material 和格内需求数量。
results列表一个或多个独立概率结果。
notify对象任务完成通知渠道。
requirements对象 / 无经济、权限、PAPI、时间与次数条件;省略表示没有条件。
money-cost数字 / 0旧 Vault 费用字段,兼容保留;新配置推荐 requirements.vault-cost

完成通知 notify

notify:
  message: true     # 聊天消息;省略时默认 true
  title: false      # 屏幕标题
  actionbar: false  # 动作栏
  bossbar: false    # 临时 BossBar
  sound: true       # 升级提示音;省略时默认 true

通知针对延时任务完成触发。消息内容来自 messages.yml → task-ready;其他通知使用配方展示名。

字符矩阵、摆放位置与材料数量

有序配方 shaped

type: shaped
matrix:
  - " D " # 第一行:中间放 D
  - " I " # 第二行:中间放 I
  - " S " # 第三行:中间放 S
ingredients:
  D: "DIAMOND*1"    # 此格至少1颗钻石
  I: "IRON_INGOT*2" # 此格至少2个铁锭;制作时从该格扣2
  S: "STICK*2"      # 此格至少2根木棍

有序配方逐格匹配:字符所在位置、材质和数量都必须满足;矩阵标记为空的位置也必须为空。空位使用普通空格或下划线 _

无序配方 shapeless

type: shapeless
matrix: ["DA_", "___", "___"] # 字符位置只用于列出需求,不限制玩家摆放
ingredients:
  D: "DIAMOND*1"
  A: "AMETHYST_SHARD*4"

无序配方按材质汇总需求数量,玩家可把材料放在任意材料槽。实际材料种类集合必须与配方一致,多余的其他材质不会匹配。

旧格式兼容

# 仍可读取,但新配方推荐使用字符矩阵。
matrix:
  1: "DIAMOND*1" # 1-9 对应3×3矩阵
  5: "STICK*2"
数量是“单个格子需求”:有序配方的 IRON_INGOT*2 要求同一位置堆叠至少2个;无序配方则会按相同材质累加。

结果物品与概率列表

results:
  - material: DIAMOND_SWORD # 必填:Bukkit Material
    amount: 1               # 数量,最小1;默认1
    chance: 100             # 百分比 0.01-100;默认100
    custom-model-data: 10001 # 可选:资源包自定义模型ID;0/省略表示不用
    display-name: "&#FFD700冒险长剑" # 名称
    lore:                   # Lore 列表
      - "&7专属冒险装备"
      - "<gradient:#FFD700:#FF6600>稀有品质</gradient>"
    glow: true              # 添加隐藏附魔以显示光效
    unbreakable: false      # 是否不可破坏

  - material: DIAMOND      # 第二结果独立判定
    amount: 2
    chance: 5.5
    display-name: "&b幸运返还"
概率语义:每个结果独立掷骰,不是“从列表中选一个”。例如第一个100%、第二个5.5%,玩家必得长剑,并有5.5%额外得到钻石。多个低概率结果可能同时获得,也可能一个都没中。
结果字段默认限制
materialSTONE必须是当前服务端有效 Material。
amount1代码最小修正为1。
chance100必须在0.01到100之间。
custom-model-data0大于0时写入 ItemMeta。
display-name材质名支持全部文本格式。
lore空列表每行支持全部文本格式。
glowfalse仅视觉光效。
unbreakablefalse设置物品不可破坏标记。

旧单结果格式

result:
  material: EMERALD
  amount: 1
  chance: 100
  display-name: "&a旧格式结果"

配方前置条件 requirements

整个 requirements 可省略。省略或使用下列零值/空列表时不会限制玩家。即时制作在提交时校验;延时制作在加入队列前及最终领取时再次校验。

完整带注释模板

requirements:
  # Vault 经济费用。0 = 不使用;旧 money-cost 仍兼容。
  vault-cost: 0

  adventure-money:
    # NONE = 关闭;MONEY = 主货币;ACOIN = A币;GCOIN = G币
    currency: NONE
    amount: 0                 # 需要并消费的数量;0 = 不使用

  # 只检查权限。玩家缺少任意一项即失败;成功后不会移除。
  permissions:
    - "adventure.vip"

  # 同样要求玩家拥有,但制作成功时通过 LuckPerms 从玩家移除。
  consume-permissions:
    - "adventure.crafting.ticket"

  # 所有 PAPI 条件为 AND 关系,必须全部满足。
  papi:
    - placeholder: "%player_level%" # 变量先解析
      operator: ">="                 # == != > >= < <= contains matches
      value: "30"                    # 值也会解析 PAPI
    - placeholder: "%player_world%"
      operator: "=="
      value: "world"

  time:
    enabled: false             # false = 不限制时段
    start: "08:00"             # HH:mm,包含开始时刻
    end: "22:00"               # HH:mm,包含结束时刻
    timezone: "Asia/Shanghai"  # Java ZoneId

  craft-limit:
    max-crafts: 0              # 0 = 不限制
    period-days: 0             # 0 = 终身累计;大于0 = 最近X×24小时滚动窗口

Vault 与 AdventureMoney

配置检查和消费失败行为
vault-cost通过 Vault 检查余额并扣款。余额不足时拒绝;后续数据库写入失败会退款。
MONEYAdventureMoney 主货币。插件不可用、余额不足或扣款失败时拒绝。
ACOINAdventureMoney A币。同上。
GCOINAdventureMoney G币。同上。

Vault 与 AdventureMoney 可以同时配置,此时两项都必须满足并都会消费。建议只在确实需要“双货币成本”时同时启用。

权限检查与权限消费

  • permission(配方顶层)和 requirements.permissions 都只检查,不移除。
  • consume-permissions 只有在产出事务成功时才消费;数据库失败时会尝试恢复权限。
  • 消费功能需要 LuckPerms,未加载时该条件直接失败,不会绕过。
  • 票券型权限应直接赋给玩家,例如 /lp user Steve permission set adventure.crafting.ticket true。若权限来自组继承,移除玩家直接节点不会修改组本身。

PAPI 判断规则

operator用途示例
==数字相等或忽略大小写的字符串相等%player_world% == world
!=不相等%vault_eco_balance% != 0
> >= < <=双方可解析为数字时进行数值比较%player_level% >= 30
contains实际字符串包含目标文本,区分大小写VIP-高级 contains VIP
matchesJava 正则表达式匹配%player_world% matches world(_nether)?
PAPI 条件失败常见原因:变量所属扩展未安装时,PlaceholderAPI 可能原样返回 %变量%。先使用 PAPI 自带解析命令确认变量输出,再编写条件。

时间段与制作次数

普通时段

08:00 → 22:00

允许当天08:00至22:00,边界时刻也允许。

跨午夜

22:00 → 02:00

允许晚上22:00至次日02:00。

最近 X 天

max-crafts: 3
period-days: 7

最近7×24小时内最多成功制作3次。

终身限制

max-crafts: 1
period-days: 0

该玩家最多成功制作一次。

次数统计口径:只有成功产出才记入 data/craft-history.yml。失败、取消、仅创建队列均不计数。此限制历史当前是本服本地文件;若多个子服都允许制作同一限次配方,应只开放一个制作服,避免各服分别计数。

单个配方覆盖条件 Lore

右键结果物品查看需求时,默认使用 condition-lore.yml。如果某个配方想要特殊写法,可在配方根节点添加 requirement-lore。只会覆盖写到的条件 key,未写的继续回退到统一配置。

requirement-lore:
  met:
    vault: "&7金币需求:&f%value% &a✔"
    permission: "&7专属权限:&f%value% &a已拥有"
  unmet:
    vault: "&7金币需求:&f%value% &c✘"
    permission: "&7专属权限:&f%value% &c未拥有"

常用条件 key:permissionconsume-permissionvaultadventure-moneyexpconsume-explevelkilladventure-levelquesttaskskintimepapicraft-limit

完整配方例子

例1:无条件、即时、无序材料合成

recipes:
  mixed_crystal:
    display-name: "&d混合水晶"
    public: true
    default-unlocked: true
    type: shapeless
    permission: ""
    crafting-guis: ["crafting-gui"]
    craft-time: 0             # 点击后立即产出,GUI不关闭
    matrix: ["DA_", "___", "___"]
    ingredients:
      D: "DIAMOND*1"
      A: "AMETHYST_SHARD*4"
    results:
      - material: AMETHYST_SHARD
        amount: 2
        chance: 100
        display-name: "&d混合水晶"
        lore: ["&7位置不限"]
        glow: true
    # requirements 完全省略 = 无经济、权限、PAPI、时间和次数条件

例2:有序配方、延时队列、多个概率结果

recipes:
  adventurer_blade:
    display-name: "<gradient:#FFD700:#FF6600>冒险者之刃</gradient>"
    public: true
    default-unlocked: false
    type: shaped
    crafting-guis: ["crafting-gui"]
    craft-time: 30
    matrix:
      - " D "
      - " I "
      - " S "
    ingredients:
      D: "DIAMOND*2"
      I: "IRON_INGOT*4"
      S: "STICK*1"
    results:
      - material: DIAMOND_SWORD
        amount: 1
        chance: 100
        custom-model-data: 10001
        display-name: "&#FFD700冒险者之刃"
        lore: ["&7必定产物"]
        glow: true
      - material: DIAMOND
        amount: 1
        chance: 8.25
        display-name: "&b幸运返还"
      - material: NETHER_STAR
        amount: 1
        chance: 0.01
        display-name: "&d奇迹之星"
    notify:
      message: true
      title: true
      actionbar: false
      bossbar: false
      sound: true

例3:VIP、票券消费、双货币、PAPI、夜间和7天限次

recipes:
  weekly_night_box:
    display-name: "&5每周夜行宝箱"
    public: true
    default-unlocked: true
    type: shapeless
    crafting-guis: ["vip-crafting"]
    craft-time: 60
    matrix: ["ABC", "___", "___"]
    ingredients:
      A: "DIAMOND*8"
      B: "EMERALD*16"
      C: "CHEST*1"
    results:
      - material: CHEST
        amount: 1
        chance: 100
        custom-model-data: 20010
        display-name: "&5夜行宝箱"
    requirements:
      vault-cost: 5000
      adventure-money:
        currency: ACOIN
        amount: 20
      permissions: ["rank.vip"]
      consume-permissions: ["adventure.ticket.weekly-box"]
      papi:
        - placeholder: "%player_level%"
          operator: ">="
          value: "50"
      time:
        enabled: true
        start: "20:00"
        end: "02:00"
        timezone: "Asia/Shanghai"
      craft-limit:
        max-crafts: 1
        period-days: 7

例4:只允许第二个 GUI 制作

# guis/crafting-gui-2.yml
open-permission: "adventurecraftings.gui.crafting-gui-2"
title: "&1高级工坊"
rows: 6
# 其余布局参考默认文件……

# recipes/high-tier.yml 中的配方
recipes:
  high_tier_item:
    display-name: "高级物品"
    type: shaped
    default-unlocked: true
    crafting-guis: ["crafting-gui-2"] # 默认 /craft 中不会匹配
    craft-time: 0
    matrix: ["AAA", "ABA", "AAA"]
    ingredients:
      A: "DIAMOND*1"
      B: "NETHER_STAR*1"
    results:
      - material: BEACON
        chance: 100
        display-name: "&b高级信标"

指令

指令权限说明
/craftadventurecraftings.use + GUI权限打开默认 crafting-gui
/craft open <GUI-ID>对应 open-permission打开指定 GUI;支持 Tab 补全已加载 ID。
/craft book打开公开配方书。别名:/craft recipes
/craft editoradventurecraftings.editor打开可视化配方编辑器。
/craft editor toolsadventurecraftings.editor打开维护工具:配方搜索、公开/私有筛选、原版工作台筛选、健康检查、导入导出。
/craft info查看版本、服务端ID和配方数量。别名:/craft version
/craft help显示帮助。
/craft admin reloadadventurecraftings.admin热重载配置、消息、GUI、配方并广播版本。
/craft admin statusadmin查看 MySQL、Redis、本地玩家与配方状态。
/craft admin syncadmin同步本地解锁和降级日志到 MySQL。
/craft admin unlock <玩家> <配方ID>admin为玩家解锁配方。
/craft admin lock <玩家> <配方ID>admin锁定玩家配方。
/craft admin give <玩家> <配方ID>admin向在线玩家发放该配方的第一个结果。
/craft admin clearqueue <玩家>admin清除玩家全部制作任务。
/craft admin log <玩家>admin查看最近20条合成记录。
管理操作优先使用完整 /craft admin ... 形式。插件还兼容部分直接子命令,但不建议写入菜单或脚本。

配方编辑器 /craft editor

v3.9.7 新增内置配方编辑器。编辑器直接读写 plugins/AdventureCrafings/recipes/ 下的 YAML 文件,点击保存后自动热重载配方。

配方列表

显示全部已加载配方。每个配方 Lore 末尾显示 [左键编辑] | [右键两次删除该配方]。右键删除有 6 秒二次确认,避免误删。

详细设置

左键编辑后进入五类入口:文件名编辑、摆放与布局编辑、制作结果编辑、前置条件编辑、配方属性编辑。

聊天输入

需要文本/数字输入的按钮会关闭 GUI,并监听管理员下一条聊天。输入被取消发送到公屏,验证后自动回到原 GUI。

安全写入

文件路径只允许相对路径和 .yml,禁止绝对路径、..、越界写入。保存前所有改动只存在管理员草稿中。

文件夹筛选与批量移动

编辑器主列表顶部显示已存在的配方分类文件夹。点击文件夹可筛选该分类;点击“全部配方”返回总览。对配方 Shift+左键可加入批量选择,点击“批量移动选中配方”后输入目标文件夹,插件会自动创建目录、迁移 YAML、清理空目录并记录审计。

热刷新:单配方保存/删除使用单配方缓存刷新;批量移动会在批处理完成后统一热重载并广播多服版本。

五类编辑页

页面功能
文件名编辑修改配方文件路径,支持 文件夹1/文件夹2/新名字.yml。保存时自动创建文件夹,并从旧文件移除该配方。
摆放与布局编辑拖拽材料到 3×3 区域,切换有序/无序,切换公开配方书显示,保存布局到草稿。
制作结果编辑在结果槽放置多个物品;右键结果槽输入概率 0.01-100;Shift+左键删除结果。
前置条件编辑支持添加/删除权限、消耗权限、Vault、AdventureMoney、PAPI、时段、次数、原版属性、击杀、冒险等级、任务、签到、天赋点、皮肤等条件。
配方属性编辑设置显示名、制作权限、制作时间、默认解锁、允许 GUI、完成提醒、条件 Lore 覆盖。
建议:编辑器适合日常新增和快速调整;非常复杂的 YAML(例如大量 PAPI 条件或特殊 Lore 排版)仍建议保存后在文件中精修,再执行 /craft admin reload

编辑器维护工具 /craft editor tools

v3.9.5 起新增,v3.9.7 起全部用户可见文案移动到 messages.yml → editor-tools。它不是替代 /craft editor 的编辑页,而是面向后期维护、巡检、迁移和备份的工具 GUI。

分页搜索

支持按配方 ID、展示名、所在文件夹/相对路径搜索。搜索输入会拦截聊天,不会发送到公屏;输入 clear 可清空。

筛选器

支持按公开/私有筛选,也支持按是否启用原版工作台制作筛选。配方数量多时不再只靠分页翻找。

健康检查

列出重复 ID、非 yml 文件、缺少 recipes 根节点、缺少材料/结果、非法材料、非法槽位、非法数量、非法概率和非法音效。

导入导出

左键单个配方可导出;按钮可全量导出。导入目录为 plugins/AdventureCrafings/imports,导入前会检查重复 ID、非法 ID、缺少根节点和目标文件覆盖风险。

导入/导出目录

目录说明
imports/把待导入的 .yml 放在这里,然后在 /craft editor tools 点击 Import Folder。导入会拒绝非安全文件名、重复 ID 和已存在目标文件,避免覆盖炸档。
exports/recipes-时间戳/导出的单配方或批量配方会按时间戳创建目录。配方 ID 中不适合 Windows 文件名的字符会自动转换为下划线。
backups/recipes-revisions/编辑器保存或移动配方前,会先备份旧文件。用于手动回滚误改。
backups/recipes-delete/删除配方时保存单配方备份。删除仍应谨慎,恢复需要人工拷贝回 recipes 目录。

健康检查项目

检查项为什么重要
重复 ID同名 ID 跨文件夹也不允许重复,否则实际加载结果不可控。
非 yml 文件配方目录只应保存 YAML,避免误放临时文件、备份文件影响维护。
缺少 recipes 根节点插件只读取 recipes: 下的配方。
缺少材料/结果防止 0 材料刷物、空结果配方和残缺配方。
非法材料/音效避免重载时报错,尤其是跨版本 Material 或 Sound 名称变化。
数量/概率范围概率必须在 0.01-100,数量必须为正数且不超过安全上限。
注意:导入功能不会覆盖已有文件。若你确实要覆盖,请先手动备份并删除目标文件,再导入;这样能避免一个导入文件误覆盖掉同文件中的其他配方。

权限

权限默认说明
adventurecraftings.use所有玩家使用默认 /craft
adventurecraftings.adminOP管理指令组。
adventurecraftings.editorOP打开和使用 /craft editor
adventurecraftings.queue.6false最多6个队列槽。
adventurecraftings.queue.7false最多7个队列槽。
adventurecraftings.queue.8false最多8个队列槽。
adventurecraftings.queue.9false最多9个队列槽。
adventurecraftings.queue.10false最多10个队列槽。
GUI open-permission由服主定义每个 GUI 文件独立设置。
配方 permission由服主定义每个配方独立制作权限。

队列容量从 settings.yml → default-slots 开始,插件按6到上限依次检查权限。通常给高级组授予最高一档即可。

PlaceholderAPI 变量

推荐使用正确拼写 adventurecraftings;旧标识 adventurecrafings 完全兼容。以下任一变量都可将标识替换为旧拼写。

变量返回
%adventurecraftings_queue_tasks%玩家占用队列槽的任务数量。
%adventurecraftings_ready_tasks%已完成、待领取任务数。
%adventurecraftings_queue_slots%玩家当前最大队列槽数量;离线查询默认返回5。
%adventurecraftings_today_crafts%今日成功合成次数。
%adventurecraftings_total_crafts%累计成功合成次数;crafts 为别名。
%adventurecraftings_unlocked_recipes%已解锁配方数,包含默认解锁配方;unlocked_count 为别名。
%adventurecraftings_total_recipes%当前已加载配方总数。
%adventurecraftings_recipe_unlocked_<ID>%指定配方是否解锁,返回 true / false。
# 示例
今日制作:%adventurecraftings_today_crafts%
解锁进度:%adventurecraftings_unlocked_recipes%/%adventurecraftings_total_recipes%
长剑解锁:%adventurecraftings_recipe_unlocked_advance_sword%

数据、队列与制作生命周期

即时配方

  1. 匹配矩阵、解锁、GUI 和权限。
  2. 检查全部 requirements。
  3. 扣除 Vault / AdventureMoney 和矩阵材料。
  4. 消费 LuckPerms 票券权限。
  5. 写入合成日志。
  6. 独立判定全部概率结果并发放,记录次数;GUI保持打开。
  7. 写入失败时退材料、经济并恢复消费权限。

延时配方

  1. 提交时校验条件并创建队列任务,材料区物品退回玩家。
  2. 任务按 craft-time 计时,完成后显示待领取状态并发送通知。
  3. 玩家点击领取时重新检查条件、背包材料、经济、权限、时段和次数。
  4. 成功后才扣材料/费用、消费权限并发放概率结果。

数据库表

用途
ac_player_dataUUID、玩家名、解锁配方、累计合成数。
ac_craft_logs任务、玩家、子服、配方、时间、材料、结果摘要、来源。
ac_queue_logs队列 CREATE、COMPLETE、CLAIM、CLEAR 等事件。
不要手工删除正在使用的 Redis 队列键或数据库任务记录。修改存储地址后先完整关服、备份数据,再启动并检查 /craft admin status

故障排查

现象检查项
插件 disabled,/craft 无法执行向上查看启动阶段第一条 AdventureCrafings 异常;检查 Java 21、依赖、database.yml 和 fail-fast。
配方加载失败检查三行 matrix 是否每行3字符、ingredients 是否覆盖所有字符、Material 名称、chance 范围和重复 ID。
放入材料不匹配有序配方检查位置和单格数量;无序配方检查是否混入额外材质。
GUI 不存在确认文件位于 plugins/AdventureCrafings/guis/、扩展名为 .yml,重载时无报错;命令使用文件名而非 title。
GUI 打不开检查 open-permission,以及默认 /craft 还需要 adventurecraftings.use
配方在某 GUI 不出现检查配方 crafting-guis 是否包含当前 GUI ID。
延时成品无法领取领取时仍需背包材料,并会重新检查余额、权限、PAPI、时段和次数。
PAPI 条件永远失败确认 PlaceholderAPI 与对应扩展已安装,先单独解析变量,检查返回值类型和 operator。
权限票券没有消耗确认 LuckPerms 正常、权限直接赋给玩家;组继承权限不会从组中删除。
次数限制似乎重置检查 data/craft-history.yml 是否可写、是否更换了服务器数据目录;多子服默认各自记录。
颜色显示为文本默认用 &;Hex 用 #RRGGBB / &#RRGGBB;MiniMessage 标签必须完整闭合。
MySQL/Redis 连接失败检查地址端口、防火墙、账号密码、数据库是否已创建;临时可禁用对应服务或启用文件降级。

推荐排查顺序

完整重启服务器,不使用插件热卸载工具。
logs/latest.log 搜索 AdventureCrafings,找到最早异常而非最后一条连锁报错。
执行 /craft admin status 检查存储与已加载配方数。
使用最小无条件配方测试,再逐项恢复经济、权限、PAPI、时间和次数条件。

文本格式速查

display-name: "&a传统绿色"                          # 默认推荐
display-name: "#FFD700十六进制金色"                # 6位Hex
display-name: "&#55D9E8带&前缀的Hex"
display-name: "&{#FF6688}花括号Hex"
display-name: "<gradient:#FF0000:#00FFFF>渐变</gradient>" # MiniMessage

传统颜色代码包括 &0-&f 与格式代码 &k-&r。同一字符串若使用 MiniMessage,可使用 gradient 等标签;默认配置仍以 & 写法为主。