配置详解
本页说明 config.yml 的键。EmakiStorage 的配置分为三个文件,另两个与容量领域模型另有专页:
| 主题 | 页面 |
|---|---|
gui/storage_gui.yml 模板、gui 与 display 段 | 界面与展示 |
capacity 段、四来源容量、三级 stackLimit、缩容溢出 | 容量与缩容 |
unlock_costs.yml 付费档位 | 付费扩容档位 |
修改后执行 /estorage reload 重载配置、语言与 GUI 模板。
config.yml 顶层
version: "1.0.6"
language: "zh_CN"
release_default_data: true
op_bypass: false
debug: false| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
version | string | 1.0.6 | 默认资源版本标记,由资源同步维护。与 AppConfig.CURRENT_VERSION 同值。 |
language | string | zh_CN | 使用 lang/<language>.yml。 |
release_default_data | boolean | true | 缺失时是否释放内置 unlock_costs.yml。 |
op_bypass | boolean | false | 为 true 时 OP 视为持有 emakistorage.admin。 |
debug | boolean | false | 会被解析进配置对象,但当前实现没有任何分支读取它;调试开关请通过 /estorage debug 管理。 |
unlock
unlock:
overflow_policy: lock_readonly
purchase_enabled: true
cost_file: "unlock_costs.yml"| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
overflow_policy | enum | lock_readonly | 容量缩小导致占用超出时的处理策略,四种取值见容量与缩容。 |
purchase_enabled | boolean | true | 是否开放 GUI 内付费扩容。还需 emakistorage.unlock.purchase 权限。 |
cost_file | string | unlock_costs.yml | 付费档位配置文件名,逐键说明见付费扩容档位。 |
behavior
behavior:
overflow_on_withdraw: return
withdraw_amounts:
left: 1
right: 16
shift_left: 32
shift_right: 64
withdraw_prompt:
enabled: true
mode: "auto"
dialog:
title: "dialog.withdraw.title"
can_close_with_escape: true
pause: false
body:
- "dialog.withdraw.body"
inputs:
- type: "text"
key: "amount"
label: "dialog.withdraw.label"
max_length: 32
buttons:
- label: "dialog.confirm"
deposit_filter:
mode: blacklist
entries: []
allow_unique_items: true
multi_slot_stacking: false
batch_max_ops: 200
default_sort: amount_desc
player_sort_enabled: true| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
overflow_on_withdraw | enum | return | 取出时背包装不下的剩余部分:return 回补仓库,drop 地面掉落。 |
withdraw_amounts.left | long | 1 | 左键取出数量。 |
withdraw_amounts.right | long | 16 | 右键取出数量。 |
withdraw_amounts.shift_left | long | 32 | Shift + 左键取出数量。 |
withdraw_amounts.shift_right | long | 64 | Shift + 右键取出数量。 |
withdraw_prompt.enabled | boolean | true | 中键是否启用自定义数量输入。 |
withdraw_prompt.mode | enum | auto | 输入方式:auto 对话框可用则用对话框、否则退回聊天输入;dialog 强制对话框,不可用时该交互被禁用;chat 强制聊天输入。 |
withdraw_prompt.dialog | section | 见示例 | 对话框配置,键集见下方对话框配置块。必须保留 key: amount 的输入框。 |
deposit_filter.mode | enum | blacklist | 存入过滤模式:blacklist / whitelist / off。 |
deposit_filter.entries | list | [] | CoreLib ItemSource token 列表。 |
deposit_filter.matcher | section | 无 | 通用物品匹配器,按组件、PDC、Lore 等条件判定物品。与 entries 是或关系:任一命中即视为命中,再由 mode 决定放行还是拦截。见 物品匹配器。 |
allow_unique_items | boolean | true | 是否允许存入带唯一标记的物品。 |
multi_slot_stacking | boolean | false | 同一物品单槽存满后是否自动占用新槽位继续存储。false 时存满即拒绝剩余部分。详见容量与缩容。 |
batch_max_ops | int | 200 | 单次 applyBatchAsync 允许的最大操作数,钳制在 1–2000。超出时整批返回 batch_too_large 且不执行任何操作,见 API 与集成。 |
default_sort | enum | amount_desc | 默认排序:material_asc / material_desc / name_asc / name_desc / amount_asc / amount_desc。 |
player_sort_enabled | boolean | true | 是否允许玩家在 GUI 中切换排序。false 时强制使用 default_sort。 |
deposit_filter.mode 为 whitelist 且 entries 为空时,所有物品都无法存入。唯一标记的判定是结构化的:检查物品自身的 PersistentDataContainer 是否非空,而不是读取显示名或 lore。
这些键决定各种点击的数量与是否被允许;完整的点击语义表、被拒绝的点击方式与搜索态限制见界面与展示。
search
search:
enabled: true
operators:
name: "@"
lore: "#"
id: "$"
exclude: "!"
input:
mode: "auto"
timeout: 30
cancel_keywords: ["取消", "cancel"]
dialog:
title: "dialog.search.title"
can_close_with_escape: true
pause: false
body:
- "dialog.search.body"
inputs:
- type: "text"
key: "query"
label: "dialog.search.label"
max_length: 64
buttons:
- label: "dialog.confirm"| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
enabled | boolean | true | 是否开放搜索。 |
operators.name | string | @ | 只匹配显示名。 |
operators.lore | string | # | 只匹配 lore。 |
operators.id | string | $ | 只匹配材质 key 或 ItemSource id。 |
operators.exclude | string | ! | 排除:命中则拒绝该条目。 |
input.mode | enum | auto | 输入方式,取值同 behavior.withdraw_prompt.mode。 |
input.timeout | int | 30 | 聊天输入等待超时(秒)。 |
input.cancel_keywords | list | [取消, cancel] | 取消聊天输入的关键词。 |
input.dialog | section | 见示例 | 对话框配置。必须保留 key: query 的输入框。 |
对话框配置块
behavior.withdraw_prompt.dialog 与 search.input.dialog 使用与 EmakiCoreLib 对话框定义文件(EmakiCoreLib/dialogs/*.yml)完全相同的键集,包括 type、external_title、after_action、columns、exit_button,以及输入项的 width、initial、label_visible 等。区别只有一点:id 由插件提供,配置里不需要写。
title、body 条目的文本、输入项的 label、按钮的 label 与 tooltip 会先按语言键解析:填 dialog.withdraw.title 这类键名时读取 lang/*.yml,键不存在则按原文渲染,因此也可以直接写 MiniMessage 文本。搜索对话框的正文支持 %name%、%lore%、%id%、%exclude% 四个操作符占位符。
对话框需要客户端 1.21.6 及以上,并且 EmakiCoreLib 的 dialog.enabled 为 true。若 inputs 中缺少业务所需的 key(取出为 amount,搜索为 query)或没有任何按钮,该对话框会被判定为不可用:mode: auto 回退聊天输入,mode: dialog 则该交互被禁用并提示 dialog.unavailable。
操作符前缀可改,用于避免与物品名冲突。搜索语法规则:
- 空白分隔多个词,所有词必须同时满足(AND)。
- 一个词可同时带一个作用域前缀和一个排除前缀,顺序任意,例如
!@钻石与@!钻石等价。 - 不带作用域前缀时匹配合并文本。合并文本由「显示名 + lore + 标识符」三段拼成,因此无前缀搜索也能命中材质 key。
- 全部匹配都是子串匹配,对已经小写化并去除格式的预计算文本执行。
不提供正则搜索,也没有管理员开关:恶意正则会因灾难性回溯卡服,而子串匹配已覆盖实际需求。
auto_pickup
auto_pickup:
enabled: true
mode: on_pickup
radius: 8
max_radius: 16
scan_interval_ticks: 10
default_enabled: false
notify_cooldown_ms: 3000| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
enabled | boolean | true | 自动拾取总开关。关闭后功能整体不可用,玩家命令被拒绝。 |
mode | enum | on_pickup | 工作模式:on_pickup 仅在原版 EntityPickupItemEvent 触发时拾取(零额外开销);radius 额外启动定时扫描任务,拾取玩家周围指定半径内所有掉落物(更强但有性能成本)。 |
radius | int | 8 | radius 模式专用。扫描半径(格),全服统一。会被钳制在 1 与 max_radius 之间。on_pickup 模式忽略此值。 |
max_radius | int | 16 | radius 模式专用。radius 的钳制上限,最小为 1。 |
scan_interval_ticks | int | 10 | radius 模式专用。全服统一的扫描任务间隔(tick),最小为 1。20 tick = 1 秒;10 = 每 0.5 秒扫一次。越小响应越快,但 CPU 开销越大。on_pickup 模式忽略此值。 |
default_enabled | boolean | false | 新玩家首次加入时自动拾取的默认状态。true = 默认开启,玩家可用 /estorage autopickup off 关闭;false = 默认关闭,玩家可用 /estorage autopickup on 开启。 |
notify_cooldown_ms | long | 3000 | 成功拾取后的通知冷却(毫秒)。冷却期内的后续拾取不再发消息,避免刷屏。0 = 每次拾取都提示;3000 = 3 秒内只提示一次。 |
玩家使用 /estorage autopickup 命令管理个人开关(需 emakistorage.autopickup 权限,默认 true)。半径没有个人设置,radius 是全服统一值,只能改配置。
mode: radius 会在每个 scan_interval_ticks 对所有在线玩家执行范围扫描:单服 100 在线、scan_interval_ticks: 20 时产生 5 次/秒的全玩家扫描,需根据服务器性能调整间隔或使用 on_pickup 模式。
persistence
persistence:
autosave_interval_seconds: 300
drain_timeout_seconds: 10| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
autosave_interval_seconds | int | 300 | 自动保存间隔(秒)。0 表示仅在关闭 GUI 与下线时保存。 |
drain_timeout_seconds | int | 10 | 插件停用时等待文件写入 drain 的超时(秒)。 |
自动保存期间的多次数量变化会合并为一次写盘。每次保存都是对 storage.dat 的全量重写:先写同目录 .tmp,读回校验记录数,再原子替换。写入失败时旧文件保持不变并删除 tmp。
logging
logging:
enabled: true
retention_days: 30
sources: []| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
enabled | boolean | true | 是否记录常规流水。 |
retention_days | int | 30 | 日志保留天数。<= 0 时不清理。 |
sources | list | [] | 只记录这些来源:gui / command / api / action。留空表示全部。 |
日志目录结构是「按玩家目录 + 按日切文件」:logs/<uuid>/<yyyy-MM-dd>.log。过期文件按日删除;某玩家的日志全部过期后其目录一并删除。
ADMIN_SET、ADMIN_GIVE、ADMIN_CLEAR 三类管理员操作强制记录,不受 enabled 与 sources 影响。管理员为省磁盘关掉日志,不是丢失管理员改动审计的理由。
流水日志只写不读:业务逻辑永不读取这些文件,因此不需要索引、压实、schema 版本或跨文件事务。写入失败只记一条 warning,不会让产生它的存取事务失败。同一玩家排队的记录会合并为一次追加写,所以 36 格批量存入产生一次文件操作而不是 36 次。