Folia 与 Luminol 兼容性
状态定义
| 状态 | 含义 |
|---|---|
| 构建目标 | 项目可针对 26.2 API 编译并生成 JAR |
| 静态审查 | 检查调度包装、集合、生命周期、不可用事件、Region 所有权和阻塞调用 |
| 运行验证 | 在明确核心与构建号上完成真实服务器测试 |
当前构建目标是 Luminol/Folia/Paper 26.2、Java 25。项目资料记录的运行验证基线是 Luminol 26.2 build 726。
加载标志的边界
folia-supported: true 只允许插件加载,不证明线程安全或功能完整。运行基线也不能抵消静态规则问题;升级核心、API 或依赖后必须重新检查。
Rule 7 静态发现
| 分类 | 入口与调用链 | 当前上下文与真实所有者 | 边界值 | 终止与清理 | 命中规则 |
|---|---|---|---|---|---|
must_fix | Match、CubeBall、JoinSignManager、ResidenceBossBar、PlayerStateCache、CCBCommand 和菜单入口进入 FoliaScheduler.runRegion 或 FoliaScheduler.runEntity,再调用 RegionScheduler.run 或 EntityScheduler.run | 调用者可能位于事件、Global、Region 或 Entity 上下文;真实所有者是目标 Location 的 Region 或目标 Entity | 目标 Location、Entity 与业务 Runnable;部分调用访问实时 World、Entity、Player 或 Display 状态 | 任务句柄由 TRACKED_TASKS 跟踪并在插件关闭时取消,但清理不改变调度延迟语义 | Rule 7 |
FoliaScheduler.runRegionLater 和 runEntityLater 已通过 normalizeTicks 强制至少 1 tick。无延迟入口仍使用 run(...),没有按本项目规则显式使用 runDelayed(..., 1)。
因此当前状态不能描述为 Folia 规则全项通过。本次文档工作只披露问题,不修改 CubeCubeBall 插件。
传送
传送统一进入:
FoliaScheduler.teleport -> Entity.teleportAsync
代表调用包括比赛准备、大厅/退出传送。完成回调需要访问玩家实时状态时,再通过 FoliaScheduler.runEntity 返回目标实体上下文;不得在 Region 线程同步等待 Future。
调度与生命周期的其他事实
init使用RegionizedServer一次检测 Folia,并缓存结果。- 传统 BukkitScheduler 调用只位于包装器非 Folia 分支;业务代码通过
FoliaScheduler。 TRACKED_TASKS使用ConcurrentHashMap.newKeySet()。- 任务完成、实体退休、显式取消和插件关闭会移除跟踪句柄。
shutdown停止接受新任务,取消包装任务,并取消 Global/Async 或 Bukkit 任务。- Region 线程不得等待数据库、网络、文件 IO 或另一 Region。
不可用事件扫描
对当前源码定向扫描:
PlayerRespawnEventPlayerTeleportEventPlayerChangedWorldEventWorldLoadEventWorldUnloadEvent
没有发现这些事件的监听器,因此没有使用类或监听方法需要列出。该结论只适用于当前 1.1.2 与 26.2 目标。
部署检查
至少验证:多 Region 玩家加入、队伍选择、比赛准备传送、足球生成/清理、进球、暂停/恢复、玩家离线与恢复、Residence BossBar、CraftEngine 外观、插件关闭和完整重启。