跳到主要内容

Folia 与 Luminol

目标版本

本页结论只针对 LotteryBox 1.0.4 当前源码与下表版本。升级 Folia、Luminol、Paper 或任一依赖后必须重新审查。

构建API/核心Java产物
1.21.11Folia 1.21.11Java 21LotteryBox-1.0.4-1.21.11.jar
26.1.2Folia 26.1.2 stable build 8Java 25LotteryBox-1.0.4-26.1.2.jar
26.2Luminol 26.2 build 726 stableJava 25LotteryBox-1.0.4-26.2.jar

folia-supported: true 只是一项加载声明,不证明线程安全、功能完整或第三方依赖兼容。

静态审查结果

规则证据与结论分类
启动检测onEnable 早期调用一次 SchedulerUtil.initialize(),结果缓存于静态字段;后续读取缓存无硬规则命中
调度封装业务调度集中进入 SchedulerUtil;Folia 路径直接调用官方 Entity、Region、Global、Async API,没有反射拼装调度无硬规则命中
传统调度定向扫描到的 Bukkit.getScheduler() 只在 SchedulerUtil 的非 Folia 分支无硬规则命中
至少一 tick非拥有上下文的 Entity/Region 调度进入 runDelayed(..., 1);延迟参数用 Math.max(1, ticks);已经拥有目标上下文时直接执行,不发生跨 Region 调度无硬规则命中
Region 所有权Folia 使用 Bukkit.isOwnedByCurrentRegion(entity/location);Paper 分支才使用 Bukkit.isPrimaryThread()无硬规则命中
共享集合付款 token、抽奖会话、编辑锁、复制状态、箱注册表、次数表和全息表使用 ConcurrentHashMap、并发 Set、快照或显式同步尚未发现 must_fix;真实负载仍待运行时验证
传送定向扫描未发现同步 teleport,当前业务也没有需要迁移到 teleportAsync 的传送操作无硬规则命中
生命周期onDisable 注销监听器,取消午夜任务,关闭 metrics,并清理编辑、复制、购买、抽奖、全息状态,最后同步落盘尚未发现 must_fix;异常终止不执行正常禁用流程

当前静态审查未发现需要在本次文档任务中标记为 must_fix 的 LotteryBox 硬规则违规。这个结论不是实时服务器证明;缺少目标生产服日志、压力负载、经济后端契约与故障注入结果的场景均属于 uncertain,不能补成“应该安全”。

五种不可用事件扫描

按当前 Folia 规则,以下事件在 Folia 层不可用,原因均为 Folia 层没有暴露可调用 API:

  • PlayerRespawnEvent
  • PlayerTeleportEvent
  • PlayerChangedWorldEvent
  • WorldLoadEvent
  • WorldUnloadEvent

本次对 src/main/java 的定向扫描没有发现任何类监听以上五种事件,因此没有可列出的命中类或监听器。若未来新增其中任一事件,必须重新报告具体类与监听器,不能假定它会工作,也不能在未收到明确需求时用未验证替代方案掩盖。

所有权与数据边界

实时 Player、Entity、World、Chunk、Block 与 Inventory 只能在所属 Entity/Region 上下文访问。跨边界流程应遵守:

  1. 在所有者上下文读取 UUID、名称、坐标副本、金额、货币 ID、奖品副本等快照;
  2. 有界异步任务处理经济或文件工作;
  3. 使用 runAtEntityrunAtRegion 回到所有者上下文修改实时状态;
  4. 在终止路径清理 token、任务、锁和引用。

Global 或 Async 上下文不能因为“能执行”就直接读写玩家背包或方块。Folia 下也不能用 Bukkit.isPrimaryThread() 判断目标 Region 所有权。

一 tick 边界

调用另一个 Entity/Region 的调度至少晚一 tick,这是 Folia 模型本身的约束。LotteryBox 当前封装的策略是:

  • 已在目标所有者上下文:直接同步执行当前逻辑;
  • 不拥有目标上下文:调度到目标并强制至少一 tick;
  • Global:使用 GlobalRegionScheduler;
  • 纯 I/O 或经济工作:使用 AsyncScheduler,但不碰实时状态。

不要通过反射、阻塞 Future 或跨 Region 锁绕过这一 tick,否则可能造成死锁、Region 饥饿或服务器崩溃。

运行时验证清单

静态审查不能替代真实 Folia/Luminol 测试。至少验证:

  • 两名玩家在不同 Region 同时抽不同箱和同一箱;
  • 快速连点、关闭 GUI、传送离开、退出服务器与背包满;
  • DIRECT 扣款中改价、移除货币、切换模式或删除箱子;
  • 经济后端超时、抛异常、扣款成功后退款失败;
  • KEY 错箱、堆叠钥匙、动画启动失败和离线掉落;
  • /lb reload 与正常停服后的任务、缓存、监听器和数据清理;
  • 升级核心后重新核对官方 API、事件可用性和所有权检查。

以上属于运行时验证边界;没有真实日志支持时,不应写成已经通过。