Skip to content

EmakiStorage

EmakiStorage 是 Emaki 系列的 GUI 仓库模块。它把玩家物品存进按逻辑槽位组织的仓库中,单个槽位可以存放 long 量级的数量,同时完整保留原始 ItemStack(组件、附魔、PDC 全部原样保存)。

仓库界面由 gui/storage_gui.yml 模板描述,容量由 config.yml 与权限档位、命令授予、付费购买共同决定,存取行为通过 CoreLib Action、公开 API 与 Bukkit 事件对外开放。

基本信息

项目
模块版本1.0.1
API Jaremaki-storage-api-1.0.1.jar
主类emaki.jiuwu.craft.storage.EmakiStoragePlugin
主命令/emakistorage
别名/estorage
硬依赖EmakiCoreLib
软依赖PlaceholderAPI
描述符基线api-version: "1.21.8"folia-supported: true
JavaJava 25
主要权限emakistorage.use(默认 true)、emakistorage.unlock.purchase(默认 true)、emakistorage.reload(op)、emakistorage.debug(op)、emakistorage.admin(op)

功能页面

页面内容
命令与权限/emakistorage/estorage 的子命令、权限节点与示例。
配置详解config.ymlunlockbehaviorsearchpersistencelogging 等键。
容量与缩容capacity 段、四来源容量、三级 stackLimit 与缩容溢出策略。
界面与展示guidisplay 段、gui/storage_gui.yml 模板结构与点击语义。
付费扩容档位unlock_costs.yml 的档位、逐格计价与支付顺序。
CoreLib 动作EmakiStorage 注册到 CoreLib ActionRegistry 的 5 个动作。
API 与集成第三方插件通过 emaki-storage-api 调用仓库的方式与结果模型。
事件 APIStorageDepositEventStorageWithdrawEventStorageUnlockEvent 三个 Bukkit 事件。
PlaceholderAPI 占位符emakistorage 扩展的 10 个占位符与求值线程约束。

核心能力

  • 单槽 long 量级存储:一个逻辑槽位存放一种物品,数量上限来自三级 stackLimit 配置,而不是原版 64/99 堆叠。
  • 完整保留原始物品:去重口径是全量 ItemStack#equals(组件、附魔、自定义 PDC 全部参与比较),不引入任何哈希签名层,因此两个组件不同的同材质物品不会被合并成一个条目。
  • 槽位是唯一容量真实来源effectiveSlotsbase_slots + 权限档位 + 命令授予 + 付费购买四个来源相加后钳制得出,页数由槽位数推导(ceil(effectiveSlots / 每页格数)),不存在「先定页数再算槽位」的反向推导。
  • 混用存入:展示区任意槽位(光标带物品时点击)与固定投入口 deposit_slot 两条路径共用同一套事务实现,容量检查、过滤器、事件发布与流水记录只存在一份。
  • 1–99 占用率渲染display.amount_mode: percent 时用物品 amount 字段的 1–99 表达占用百分比,精确数量写进 lore。max_stack_size 组件的合法范围就是 1–99,因此不涉及任何发包技巧。
  • 搜索与排序:搜索为子串匹配,永不编译正则;排序是显式「整理」动作,会重写条目顺序。
  • 零丢失缩容:容量调小导致占用超出时有四种策略,全部不会造成不可逆数据丢失,不提供 drop / delete
  • 流水日志只写不读:业务逻辑永不读取日志文件,ADMIN_SET / ADMIN_GIVE / ADMIN_CLEAR 三类管理员操作强制记录。

存档设计

主题实现
条目数据二进制单文件 storage.dat,文件魔数 EMSTOR,格式版本 1
写入策略全量重写,不是追加写。每次保存都产出一个已经紧凑的文件,因此没有压实器、没有垃圾率统计、没有悬空 id 修复。
写入顺序先写同目录 .tmp,再读回校验记录数,最后原子替换。写入失败时保留旧文件并删除 tmp。
逐条目分帧每条记录单独分帧,使用 Paper 的 ItemStack#serializeAsBytes() / deserializeBytes(byte[]),携带 DataVersion 并在读取时过 DataFixer。
损坏隔离解码失败的记录被写入 corrupt/<uuid>-<时间戳>.dat,其余记录正常载入。
可手改数据槽位数、stackLimit、排序模式等存在 meta.yml(文本 YAML),条目载荷保持二进制,因为 YAML 无法表达完整 ItemStack

文件结构

服务器运行后,EmakiStorage 主要使用以下文件:

text
plugins/EmakiStorage/
├─ config.yml
├─ unlock_costs.yml
├─ gui/
│  └─ storage_gui.yml
├─ lang/
│  ├─ zh_CN.yml
│  └─ en_US.yml
├─ data/
│  └─ <uuid>/
│     ├─ storage.dat
│     └─ meta.yml
├─ logs/
│  └─ <uuid>/
│     └─ <yyyy-MM-dd>.log
├─ corrupt/
└─ exports/
路径说明
config.yml主配置:界面、容量、扩容缩容、展示、存取行为、搜索、持久化、日志。
unlock_costs.yml付费扩容档位。业务数据文件,只在缺失时释放一次,版本升级不覆盖管理员内容。
gui/storage_gui.yml仓库界面模板。功能区只配 offset,槽位号由 gui.storage_rows 换算。
lang/*.yml界面、命令、扩容与控制台提示文案。
data/<uuid>/storage.dat该玩家的条目数据,二进制全量重写。
data/<uuid>/meta.yml该玩家的槽位数、stackLimit、排序模式等可手改元数据。
logs/<uuid>/<yyyy-MM-dd>.log存取流水,按玩家目录 + 按日切文件,只写不读。
corrupt/解码失败记录的隔离目录。
exports//estorage export 生成的可读 YAML 转储。

快速开始

  1. EmakiCoreLib-*.jarEmakiStorage-*.jar 放入服务器 plugins/
  2. 不要把 emaki-storage-api-*.jar 放进服务器 plugins/;API Jar 只给开发者作为编译依赖使用。
  3. 首次启动后检查 plugins/EmakiStorage/config.ymlunlock_costs.yml
  4. 打开自己的仓库:
text
/estorage
  1. 修改配置后重载配置、语言与 GUI 模板:
text
/estorage reload
  1. 给在线玩家追加槽位并查看容量拆解:
text
/estorage slot grant Steve 10
/estorage info Steve

使用提示

  • gui.deposit_feedback 不建议设为 none。混用存入下物品会按条目顺序落位,可能出现在别的页,没有反馈时玩家会以为物品消失。
  • emakistorage.slots.<n>emakistorage.stacklimit.<n> 取所有生效档位中的最大值,且不支持通配
  • 调小 capacity.base_slots 不会吃掉玩家已授予或已购买的槽位,这三个来源分别持久化。
  • 缩容溢出状态不持久化,它由容量与占用推导,在登录、重载、权限变化、命令授予时重新计算。
  • 写类管理命令要求目标玩家在线,见 命令与权限