简体中文
配置详解
plugins/EmakiStation/config.yml 里的每一段与每一个键, 包括默认值和取值范围
plugins/EmakiStation/config.yml 是主配置, 队列默认值, 容量上限, EmakiStorage 通道, 持久化与界面刷新都归它管
version 是配置结构标记, 插件靠它把新增的默认键合并进来. 它跟模块的发布版本不同轨, 你不需要手工改成插件版本
发货默认值
插件随 Jar 释放的 config.yml 默认内容:
yaml
version: "1.1.8"
language: "zh_CN"
release_default_data: true
queue:
base_length: 3
permission_tiers: true
max_length: 32
progress_mode: "offline"
cancel_refund_rate: 1.0
tick_interval: 20
speed_multiplier: 1.0
purchase:
enabled: true
cost_file: "queue_costs.yml"
limits:
max_pending_claim: 100
warn_material_types: 50
batch_multiplier_max: 0
storage:
enabled: true
batch_max_ops: 200
persistence:
autosave_interval_seconds: 60
save_on_submit: true
gui:
click_throttle_ms: 200
refresh_interval_ticks: 20顶层键
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
version | string | 否 | "1.1.8" | — | 配置结构的版本标记, 由默认资源同步流程维护. 源码里另有一个迁移常量 1.0.2, 两者不要混用 |
language | string | 否 | "zh_CN" | — | 语言文件名, 对应 lang/<language>.yml |
release_default_data | boolean | 否 | true | true, false | 首次启动时是否释放示例数据 (stations/, gui/, recipes/ 等内置默认文件). 改成 false 后, 已经存在的文件不会被覆盖, 也不会再补上缺失的示例 |
queue 队列默认值
每个工作站都可以在自己的 stations/<id>.yml 里覆盖这里的同名键 (只有 purchase 由主配置统一控制, 工作站那边另外用 queue.allow_purchase 单独开关)
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
base_length | integer | 否 | 3 | 1~64, 越界截断 | 基础队列长度. 只有 WAITING / RUNNING 这两类条目占队列长度, PENDING_CLAIM 不占 |
permission_tiers | boolean | 否 | true | true, false | 是否启用 emakistation.queue.<n> 权限分级. 启用后取玩家拥有的最高一档, 没有这一前缀的权限就保持基础长度 |
max_length | integer | 否 | 32 | base_length~64, 越界截断 | 队列长度的硬上限, 权限档和购买额度都不能突破 |
progress_mode | string | 否 | "offline" | offline, online | 队首的计时方式. 填了无法识别的值会改回 offline. offline 按真实时间推进, online 只在玩家在线时累计 |
cancel_refund_rate | double | 否 | 1.0 | 0.0~1.0, 越界截断 | 取消条目时退还材料的比例. 材料和已经付掉的货币按同一比例折算 |
tick_interval | integer | 否 | 20 | 10~100, 越界截断 | 队列推进任务的间隔 (tick, 1 tick 是 1/20 秒). 全服只有这一个定时器 |
speed_multiplier | double | 否 | 1.0 | ≤0 按 1.0 处理, 上限 100.0 | 全局的配方耗时倍率, 会乘到 duration_seconds 上 |
purchase.enabled | boolean | 否 | true | true, false | 付费队列位的全服总开关. 工作站自身还要 queue.allow_purchase 为 true 才会出售队列位 |
purchase.cost_file | string | 否 | "queue_costs.yml" | —, 空/空白回退默认文件名 | 价格档位的文件名, 相对插件数据目录. 文件缺失或者没有可用价格时, 购买会被拒绝 |
pending_claim 不占用队列长度是故意这么设计的: 不然背包和仓库同时满的你, 会被自己没领走的产物锁死队列
cancel_refund_rate 不按进度折算, 这也是有意简化. 队列是一条线依次推进, 只有排在最前面的条目有进度; 为了一个几乎不会出现的情况去给每个条目记进度不值得
注意 progress_mode: offline 只表示「计时继续」, 不表示「离线发货」. EmakiStorage 拒绝对离线玩家做任何写操作, 所以离线期间到点的条目只是「已到期」, 真正结算发生在你下次上线时
价格文件缺失, 为空或者没有任何可用价格时, 购买一律被拒绝, 而不是免费放行
yaml
# 示例: 缩短队列推进间隔到 10 tick, 并把基础长度提高到 5
queue:
tick_interval: 10
base_length: 5limits 容量上限
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
max_pending_claim | integer | 否 | 100 | 1~10000, 越界截断 | 一个玩家最多能攒下多少件未领取产物 (所有工作站合起来算). 到上限后再提交会被拒绝, 返回 station.pending_claim_full |
warn_material_types | integer | 否 | 50 | 1~10000, 越界截断 | 一个配方的材料种类数超过这个值时, 只记一条 station.recipe_many_materials 警告, 不会拦下加载 |
batch_multiplier_max | long | 否 | 0 | 0 或正数, 负数截断为 0 | 一次提交的最大倍率, 0 表示不额外限制.目前源码只解析并保存这个值, 提交时没有任何强制校验, 实际的上限仍然由材料和余额决定 |
配方的材料种类数不受 GUI 槽位数量限制, warn_material_types 只是防你手滑写多了一层提醒
storage 仓库通道
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
enabled | boolean | 否 | true | true, false | 总开关. 关闭后 EmakiStation 完全不调用 EmakiStorage |
batch_max_ops | integer | 否 | 200 | 1~10000, 越界截断 | 一批最多多少个操作, 与 EmakiStorage 的 behavior.batch_max_ops 对应. 超过会把这一批拒绝掉 (station.storage_batch_too_large) |
就算 enabled 是 true, 仓库通道也还需要 EmakiStorage 提供 emakistorage:atomic_batch 能力 (一批操作要么全做要么全不做的批量接口) 才会启用. 缺这个能力时不会改成逐个 withdraw: 那样材料会在你的背包里闪现一次, 反而留下一个可以被利用的时间缝隙
材料同时来自背包和仓库时, 插件会优先用 emakistorage:reservation 能力: 先在仓库挂上预留 (不真正取出), 再扣背包, 最后把预留提交掉. 中途失败只要释放预留即可, 而释放不会因为仓库容量不足而失败. 如果 EmakiStorage 版本较低, 没有这个能力, 就会改成「先扣仓库, 失败再存回」; 存回本身可能因为容量不足被拒, 所以不如预留这条路稳
yaml
# 示例: 只从背包供料, 完全不碰仓库
storage:
enabled: falsepersistence 持久化
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
autosave_interval_seconds | integer | 否 | 60 | 5~3600, 越界截断 | 自动保存的间隔 (秒). 实际调度周期是 max(100 tick, 秒数 × 20). 旧键 autosave_interval 仍然会读, 并在启动时告警, 让管理员迁移到新键 |
save_on_submit | boolean | 否 | true | true, false | 提交成功后是否立刻写到文件, 而不是等到下一次自动保存 |
队列文件里的条目对应的是「已经扣掉的材料」, 所以这个自动保存间隔比仓库那边更短
队列文件和仓库文件是两份独立的文件, 服务器硬崩溃时两者仍可能对不上 (材料扣了但条目没存, 或者条目存了但扣料没写到文件). 好在每个条目都完整记着消耗清单, 方便你人工对账. 想彻底消掉这个空档需要跨插件的两阶段提交, 代价太高
gui 界面
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
click_throttle_ms | integer | 否 | 200 | 0~5000, 越界截断 | 同一个界面会话里两次点击的最小间隔 (毫秒). 0 表示不做限制 |
refresh_interval_ticks | long | 否 | 20 | 5~200, 越界截断 | 已经打开的界面刷新进度显示的间隔 (tick), 运行时按至少 50 毫秒处理. 旧键 refresh_interval 仍然会读, 并在启动时告警, 让管理员迁移到新键 |
yaml
# 示例: 放宽连点节流, 并让界面每 10 tick 刷新一次
gui:
click_throttle_ms: 300
refresh_interval_ticks: 10