Skip to content

这页用于说明 HNWarehouse 当前版本的正式存储后端、运行时 Session、旧 YAML 迁移机制与日常运维排查重点


当前存储方式

当前版本的正式持久化主路径已经切到数据库后端

当前实现特点:

  • 主后端由 HNCore 的 DatabaseManager 驱动
  • 仓库系统不再把 plugins/HNWarehouse/data/players/*.yml 作为正式主数据源
  • 旧 YAML 目录现在主要是历史迁移来源
  • 物品 payload 统一复用 HNCore ItemCodec,不是业务仓库自己再维护一套额外物品序列化协议

也就是说:

  • 日常运行时以数据库中的玩家仓库档案为准
  • 旧 YAML 主要用于从历史版本升级时的导入
  • 运维排查也应优先围绕 status / inspect / routecheck 与数据库状态展开,而不是默认去找玩家 YAML 文件

当前数据结构概览

当前仓库数据已经按业务职责拆成数据库层结构,典型可以理解为以下几类:

  • accounts:玩家仓库账户级元数据与总体状态
  • pages:玩家实际拥有的仓库页骨架与页级属性
  • entries:每个页面内的物品条目
  • purchases:一次性购买状态
  • unlocks:一次性解锁状态
  • expansions:页扩容状态

这意味着当前不再是“整份玩家 YAML 全量覆盖写回”的思路,而是:

  • 仓库账户、页面、条目、购买、解锁、扩容状态分层持久化
  • 条目层可以按页面局部重写,不必每次都把整份玩家仓库全量序列化一遍
  • 物品内容统一通过 HNCore ItemCodec 存取,减少多个插件并存时的物品协议分裂

关于物品 payload

当前条目里的物品快照不是 HNWarehouse 私有格式,而是统一走:

  • HNCore ItemCodec

这带来的好处是:

  • 物品编解码语义与 HNCore 公共协议保持一致
  • 更适合和邮件、奖励、签到、仓库这类需要保存物品快照的模块协同
  • 后续做迁移、兼容或坏数据隔离时更容易统一处理

运行时 Session 行为

当前仍保留 PlayerItemSession 作为运行时内存态,但行为已经不是旧式同步落盘模型。

主要行为:

  • 玩家加入时:异步加载 session
  • 玩家退出 / 被踢出时:异步保存并卸载 session
  • 自动保存:按配置间隔异步执行
  • 插件关闭时:统一 flush
  • reload:管理员触发后后台执行重载,期间仍保留安全收尾与 session 保存语义

关于 unloadSession()

当前实现已经修复“先把 session 从内存移除,再执行保存”的丢档风险。

这意味着:

  • 退出 / 卸载流程现在会优先保证保存链路安全完成
  • 不建议再用旧认知理解成“玩家一退就立刻同步写完、否则就一定丢档”
  • 更准确的理解是:运行时以 Session 为主、持久化以异步安全保存为主、关闭阶段再做统一 flush

自动保存

相关配置:

yml
storage:
  autosave-interval-seconds: 60

说明:

  • 单位是秒
  • 0 表示关闭自动保存
  • 当前 autosave 在异步任务中执行
  • 主要目的是避免把完整批量落盘压在主线程上

运维建议:

  • 测试服可以适当缩短,方便验证写入行为
  • 正式服不要把间隔调得过于激进,否则虽然不一定直接卡主线程,但仍可能增加数据库压力
  • 如果你已经有大量离线查询、频繁投递与高在线人数,建议结合数据库负载一起观察,而不是只盯着“写入快不快”

离线摘要缓存

当前离线仓库摘要查询有一层短 TTL 缓存

它的作用是:

  • 减少短时间重复查看离线玩家仓库时的数据库读取
  • 避免管理场景中连续 inspect / 摘要查询反复打库

当前语义建议理解为:

  • 这是短缓存,不是长期结果缓存
  • 写入发生后会主动失效相关缓存
  • 主要影响的是离线玩家摘要查询,不是在线 Session 内部状态

如果你发现短时间连续查看同一个离线玩家时结果一致,这是正常现象;优先确认是否落在摘要缓存时间窗内。


旧 YAML 自动迁移

旧版本目录仍可能存在:

text
plugins/HNWarehouse/data/players/

当前启动时会把它当成迁移来源扫描。

当前迁移语义

  • 启动时扫描旧 data/players/*.yml
  • 只有数据库中还不存在该玩家档案时才会导入
  • 成功后会写入:
text
plugins/HNWarehouse/data/.migration-complete
  • 原始 YAML 文件不会被自动删除

这意味着什么

  • 旧 YAML 现在更像“历史导入源”,而不是正式主数据目录
  • 如果你已经完成迁移,后续新增玩家不应再默认依赖 YAML 生成
  • 保留原始 YAML 的目的是给升级后的人工核对与回退留余地

恢复性与坏数据处理

当前读取数据库条目时,会尽量做坏数据隔离

建议理解为:

  • 如果个别 entry 损坏,会跳过坏条目并记录警告日志
  • 单条坏数据不会直接阻断整份玩家仓库档案加载
  • 排查时不要因为一条物品坏了,就默认整份仓库都不可恢复

这对仓库系统尤其重要,因为条目层天然更容易出现:

  • 历史物品结构变化
  • 跨版本物品 payload 差异
  • 外部插件联动带来的异常物品内容

当前目标是:尽量把损坏隔离到单条 entry,而不是放大成整档不可用。


常见排查命令

看整体运行状态

text
/hnwarehouse status

适合确认:

  • 存储后端
  • 自动保存间隔
  • 离线摘要缓存秒数
  • 当前已加载 Session 数量
  • 仓库定义与访问限制骨架

看某个玩家的仓库摘要

text
/hnwarehouse inspect <玩家>
/hnwarehouse inspect <玩家> detail
/hnwarehouse inspect <玩家> access

适合确认:

  • Session 已加载 状态是否符合预期
  • 玩家当前有多少仓库 / 页面
  • 当前锁定原因
  • 具体条目 ID 与数量
  • 离线摘要是否已命中短缓存

看为什么投递失败

text
/hnwarehouse routecheck <玩家> <仓库> [manual|reward|auto-collect]

适合确认:

  • 目标页是否允许该来源
  • 是否命中 item-admission
  • 是否被访问条件拦截

日常排查建议

场景 1:玩家说“仓库打不开”

先看:

  1. /hnwarehouse inspect <玩家> access
  2. 是否是 purchase / unlock / use-requirements 问题
  3. visible-when-locked 是否开启

场景 2:玩家说“物品没进仓库”

先看:

  1. 当前来源是否启用
  2. 默认目标仓库是否正确
  3. 页面 allowed-sources 是否允许
  4. item-admission 是否拦截
  5. /hnwarehouse routecheck ...

场景 3:玩家说“物品取不出来”

先看:

  1. 条目 ID 是否正确
  2. 目标页面是否正确
  3. 玩家是否在线
  4. 背包是否能正常回填
  5. /hnwarehouse inspect <玩家> detail

场景 4:为什么短时间连续查看离线玩家时像是“重复结果”

先看:

  1. 是否仍在离线摘要 TTL 缓存时间窗内
  2. 是否发生过写入导致缓存失效
  3. 当前看的是否是离线玩家而不是在线 Session

当前不建议的运维方式

当前不建议把下面这些做法当成主运维入口:

  • 直接手改数据库记录作为常规操作
  • 把旧 YAML 当成正式主档反复修
  • 仅凭磁盘文件变化判断 Session 是否已生效

更稳的顺序通常是:

  1. 先用 status / inspect / routecheck 排查
  2. 再看数据库状态与运行日志
  3. 必要时使用管理命令修复
  4. 最后才考虑人工修数据库或核对旧 YAML 迁移源

关于旧 YAML

data/players/*.yml 现在主要用于:

  • 迁移来源
  • 升级后人工比对
  • 极端情况下的历史恢复参考

它已经不适合作为“当前正式玩家仓库数据主入口”。


当前还没有的运维能力

相比更成熟的业务插件,HNWarehouse 当前还没有完整提供:

  • 面向运维的数据库一致性校验命令
  • 自动迁移报告导出
  • 批量修复工具
  • 更完整的运维后台面板

所以当前运维主路径仍然是:

  • status
  • inspect
  • routecheck
  • withdraw
  • unlockforce
  • unlockreset
  • 数据库状态与运行日志

备份建议

当前备份建议应按实际后端理解:

  • 如果使用 SQLite,应优先备份本地数据库文件
  • 如果使用 共享数据库 / 独立数据库实例,应备份数据库本体
  • 如果你仍保留旧 YAML 迁移源,也可以把 plugins/HNWarehouse/data/players/ 一并备份,作为历史迁移参考

特别建议在这些操作前先备份:

  • 大规模改 warehouses/*.yml
  • 调整仓库 ID、页 ID
  • 重新设计购买 / 解锁 / 扩容逻辑
  • 手动处理数据库中的玩家仓库异常状态
  • 首次从旧 YAML 升级到数据库版本

这样即使出问题,也更容易按“数据库主档 + YAML 历史迁移源”双层回退。

HN 系列插件文档