0.27.12 Folia 名牌跨区修复
区域所有权检查、实体下一 tick 重试、骑乘状态复用和安全限频失败处理。
日期:2026-09-04
现象与原因
旧版在 Folia/Shiroha 中刷新移动宠物的名牌时,宠物可能恰好处于区域迁移临界点。第一次名牌刷新异常会进入 PetEntityService 的容错分支,但旧容错代码又立即调用一次 PetNameplateVisibility.hasPlayerPassenger -> getPassengers()。第二次读取仍不属于当前区域线程时,异常会逃出实体调度任务,形成 Entity task ... generated an exception 警告。
用户提供的堆栈明确来自 LiPet v0.27.9-SNAPSHOT。执行 /lipet reload 不会替换 Jar 内的调度代码,必须升级插件并完整重启 Minecraft 服务端。
修复内容
- 新增独立名牌刷新协调器。执行前先用 Bukkit/Paper 区域所有权 API 核对宠物;不属于当前线程时,交给宠物实体调度器在下一 tick 执行。
- 名牌操作第一次抛出运行时异常后,只安排一次宠物实体下一 tick 重试。第二次仍失败时保留现有名牌状态,不再从异常分支读取乘客、隐藏显示实体或修改载体名称。
- 同一宠物连续失败只记录一次中文警告;后续刷新成功会清除失败标记,新的独立故障仍可报告。
- 骑乘事件在上马时立即记录隐藏状态,下马后一 tick 按最终乘客树校正;环境行为循环把已在宠物区域确认的骑乘状态直接传给名牌服务。
- ModelEngine 多层座位遍历在读取实体 UUID、PDC、载具或下级乘客前检查区域所有权,跨区旧引用不会继续访问。
nameplate.hide-while-ridden、双行文字、偏移、背景、透明度和其他管理员配置全部保留,本版没有新增配置节点。
升级步骤
- 安全停止 Minecraft 服务端并备份
plugins/LiPet/。 - 删除或移走旧
LiPet-0.27.9-SNAPSHOT.jar,确保plugins/中只保留一个 LiPet Jar。 - 放入
LiPet-0.27.12-SNAPSHOT.jar后完整启动服务端。 - 执行
/lipet status,确认实际加载版本为0.27.12-SNAPSHOT。 - 让一只带双行名牌的宠物跨越区域边界,并分别验证未骑乘、骑乘、下马与持续移动;检查控制台不再出现原堆栈。
验证
- 定向测试覆盖:非所属区域时不执行刷新、迁区异常后下一实体 tick 重试、第二次失败只报告一次且不执行不安全回退。
- 骑乘可见性测试覆盖:正常/取消的上马与下马、ModelEngine 风格的中间座位、下马后保留原 TextDisplay。
- 默认兼容构建与 Paper 26.2 API Profile 各 324 项,失败、错误和跳过均为 0。
- 最终 Jar 已在 Paper 26.2 Build 111 + PlayerPoints 3.3.5 两次加载;LiPet 使用 SQLite 正常启用,并在控制台
stop后记录“LiPet 已安全关闭”。该隔离环境没有完成 Paper 自身的世界初始化,因此本轮不把/lipet status和/lipet reload写成已验证。 - 当前工作区没有 Shiroha/Folia 服务端核心,无法声称已在相同核心完成真实跨区运行;针对用户堆栈的区域归属、延迟重试和禁止不安全回退已经由确定性测试覆盖。
- 成品:
target/LiPet-0.27.12-SNAPSHOT.jar;大小:891579字节;SHA-256:29891978E331666FDEB4FB76FEC84C07236562319AA99062B8E0B4C63D9476E3。Jar 共 462 个条目,未打入 SQLite、JUnit、Bukkit 或 Adventure 外部依赖类。