TabooLib 6.3.0 更新 - Incision 字节码织入、Minecraft 26.1 全面适配与多方块结构模块
本次更新标志着 TabooLib 进入 6.3.0 时代,涉及 315 个文件、超过 22000 行新增代码。核心亮点包括全新的 Incision 字节码织入模块、Minecraft 26.1(1.22)全面适配、多方块结构模块、NMS 转译逻辑重写,以及大量兼容性修复和基础设施改进。
涉及的相关提交
Incision 字节码织入模块
-
feat(incision): 新增字节码织入模块与 Accessor API由 @Ray_Hughes 提交 - 全新的运行时织入框架,支持注解和 DSL 双入口
-
fix(incision): suppress non-error logs outside debug mode由 @Ray_Hughes 提交 - 非调试模式下抑制非错误日志
Minecraft 26.1 全面适配
-
nms 模块初步兼容 26.1, 更改转译逻辑, 等待修复 bug。由 @Micalhl 提交 - NMS 模块初步适配 26.1
-
新的转译逻辑,Paper/Spigot 1.20.4、1.21.11、26.1 测试通过由 @Micalhl 提交 - 新转译逻辑全版本测试通过
-
新的 reflex 转译逻辑,Paper/Spigot 1.20.4、1.21.11 测试通过由 @Micalhl 提交 - Reflex 转译逻辑更新
-
分离 isUniversalCraftBukkit 和 isMojangMapping,在 Paper/Spigot 1.19.4、1.20.4、1.21.11、26.1 上测试通过由 @Micalhl 提交 - 映射判断逻辑分离
-
EntityAI、NMS stable 在 Paper/Spigot 1.21.11、26.1 上通过测试由 @Micalhl 提交 - EntityAI 和 NMS stable 模块适配
-
module-nms 模块全部通过测试由 @Micalhl 提交 - NMS 模块全面测试通过
-
ItemTag 测试通过由 @Micalhl 提交 - ItemTag 模块适配验证
-
navigation 寻路模块通过编译由 @Micalhl 提交 - 寻路模块适配
-
支持 26.1.1,升级虚拟界面模块,并修复与 tb 6.2 插件的兼容性由 @Micalhl 提交 - 26.1.1 支持与向后兼容
-
支持 26.1.2由 @Micalhl 提交 - 26.1.2 版本支持
多方块结构模块
-
feat(minecraft-multiblocks): 新增多方块结构模块由 @Ray_Hughes 提交 - 参考 Patchouli 设计的多方块结构定义与验证
NMS 与数据包改进
-
新增 Packet#nameInMojang 字段并在 Paper/Spigot 1.8.8 和 1.21.11 通过测试由 @Micalhl 提交 - 数据包 Mojang 名称查询
-
将 XSeries 强制编译到 26.1由 @Micalhl 提交 - XSeries 版本适配
PTC Object ORM 重构
-
refactor(database): 重构 ptc-object ORM 模块,拆分子包并消除重复代码由 @Ray_Hughes 提交 - 架构重构,引入设计模式
命令系统增强
-
feat(command): 添加命令组件描述功能支持由 @wxys233 提交 - 命令帮助系统增强
基础设施改进
-
feat(common): 支持 SNAPSHOT 版本依赖下载和本地仓库 SHA1 生成由 @wxys233 提交 - SNAPSHOT 依赖解析
-
更新 reflex 到 1.2.3由 @黑 提交 - Reflex 库升级
-
更新 Reflex 至 1.2.4,修复与 JDK 8 的兼容问题由 @Micalhl 提交 - Reflex 库再次升级
-
新增 identityLazy 和 weakIdentityLazy 工具由 @黑 提交 - 基于身份的懒加载委托
-
refactor(AetherResolver): fix dependency injection logic & support for JSON dependency loading由 @蛟龙 提交 - 依赖解析器重构
-
新增一个选项来强制使用旧版依赖处理工具由 @Micalhl 提交 - 依赖处理回退选项
-
调整服务端依赖,更新 servergen 工具由 @Micalhl 提交 - 服务端依赖调整
Bug 修复
-
fix: PlayerFakeOp 兼容 Java 16+ 和 Paper 1.21.8+由 @dakuo 提交 - FakeOp 全面兼容修复
-
fix: 修复 JDK 8 下 TabooLib 二次启动加载异常由 @White_Souls 提交 - JDK 8 兼容性修复
-
fix(FileWatcher): gracefully handle inotify exhaustion instead of crashing由 @Score2 提交 - FileWatcher 优雅降级
-
fix: SQLite @Id 不再生成 PRIMARY KEY, 改为普通索引由 @黑 提交 - SQLite 索引行为与 MySQL 对齐
-
fix: Velocity 命令注册未处理 permission 权限检查由 @黑 提交 - Velocity 命令权限修复
-
fix: 虚拟背包适配 1.21.8 ClientboundContainerSetContentPacket 构造器变更由 @黑 提交 - 虚拟背包高版本适配
-
fix(yaml): 修复 SnakeYAML Composer 注释事件 ClassCastException由 @黑 提交 - YAML 解析异常修复
-
修复 spigot 1.21.11 版本号读取异常由 @Micalhl 提交
-
1.21+的json禁止包含§字符由 @Jie-150 提交 - JSON 文本组件合规
-
改进版本号获取方式,支持spigot-1.21.11的版本号读取由 @Jie-150 提交 - XItemStack 版本号获取改进
-
增加写入Boolean值回调函数,Bukkit输出不过滤null值/回调输出过滤null值由 @Jie-150 提交 - 回调函数与输出过滤改进
-
修复 RemoteQuestContext#setExitStatus 逻辑异常由 @黑 提交
-
ActionPlayer 要求主线程执行由 @黑 提交 - Kether ActionPlayer 线程安全修复
一句话简述更新
Incision 织入框架让插件拥有手术刀级别的字节码能力,Minecraft 26.1 全线适配为新版本保驾护航。
本次更新的重点
1. Incision 字节码织入模块 - 手术式运行时织入
背景问题
Bukkit/Paper 插件开发中,经常需要修改服务端或其他插件的行为:Hook 方法入口/出口、替换调用点、注入诊断逻辑。传统方案要么依赖重量级的 Mixin 框架,要么手写 ASM 字节码,门槛高且难以维护。
解决方案
Incision 提供一套可控、可诊断、可回滚的手术式织入能力,同时支持注解和 DSL 两种入口,在 LifeCycle.CONST 阶段完成物理织入,运行时零额外开销。
架构总览
核心能力
注解模式(推荐用于长期稳定 patch):
@Surgeon("net.minecraft.server.MinecraftServer")
object ServerPatch {
@Lead("tick()void")
@JvmStatic
fun beforeTick(theatre: Theatre) {
// 方法入口织入 —— 在 tick() 执行前运行
}
@Trail("tick()void")
@JvmStatic
fun afterTick(theatre: Theatre) {
// 方法出口织入 —— 在 tick() 返回前运行
}
@Splice("saveLevel()void")
@JvmStatic
fun replaceSave(theatre: Theatre) {
// 完全替换方法体
theatre.resume.proceed() // 可选:调用原方法
}
}
DSL 模式(适用于临时/作用域 patch):
// 作用域内生效,离开自动回滚
Scalpel.transient {
lead("com.example.Target#process(int)void") { theatre ->
if (theatre.args[0] as Int > 100) {
theatre.resume.abort() // 条件性跳过原方法
}
}
}.use {
target.process(200) // 被拦截
}
// 离开 use 块后,patch 自动移除
7 种织入注解:
| 注解 | 作用 | 场景 |
|---|---|---|
@Lead | 方法入口前 | 参数校验、日志、计时 |
@Trail | 方法出口后 | 结果修改、清理 |
@Splice | 替换整个方法体 | 完全接管逻辑 |
@Graft | 替换特定调用点 | 替换内部方法调用 |
@Excise | 删除指令范围 | 移除不需要的逻辑 |
@Bypass | 条件跳过方法 | 版本门控、特性开关 |
@Trim | 修剪返回值 | 过滤/转换返回结果 |
三层 Backend 自动降级:
- JVMTI Native(C 原生库)—— 最强能力,支持已加载类的重定义
- Instrumentation(Java Agent)—— 标准 Agent 方式
- ClassLoader Hook —— 兜底方案,拦截类加载
NMS 版本门控
Incision 与 TabooLib 的 NMS remap 系统深度集成:
@Surgeon("net.minecraft.server.level.ServerPlayer")
@Version(min = "1.20", max = "1.21.8")
object PlayerPatch {
@Lead("hurt(net.minecraft.world.damagesource.DamageSource,float)boolean")
@JvmStatic
fun beforeHurt(theatre: Theatre) {
// 自动处理 Spigot/Paper/Mojang 映射差异
}
}
2. Minecraft 26.1(1.22)全面适配
背景问题
Minecraft 26.1 是一次重大版本更新,服务端内部结构发生了显著变化,包括类名变更、构造器签名修改、映射方式调整等,导致依赖 NMS 的功能大面积失效。
适配工作
本次适配由 @Micalhl 主导,历经 17 个提交,覆盖了 TabooLib 所有 NMS 相关模块:
关键改动:
- 转译逻辑重写:新的
RemapTranslation策略,在 Paper/Spigot 1.20.4、1.21.11、26.1 上全部测试通过 - 映射判断分离:将
isUniversalCraftBukkit和isMojangMapping拆分为独立判断,解决 26.1 下两者不再等价的问题 - Reflex 转译更新:配合 Reflex 1.2.3 → 1.2.4 升级,修复反射调用在新版本下的兼容性
- 虚拟界面升级:适配
ClientboundContainerSetContentPacket构造器变更 - XSeries 强制编译到 26.1:确保物品、粒子、音效等工具类支持新版本
- Packet#nameInMojang:新增数据包的 Mojang 名称字段,方便调试和版本适配
版本支持矩阵:
| 模块 | 1.8.8 | 1.19.4 | 1.20.4 | 1.21.11 | 26.1 | 26.1.1 | 26.1.2 |
|---|---|---|---|---|---|---|---|
| NMS Core | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| EntityAI | - | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| ItemTag | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Navigation | - | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Virtual UI | - | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
3. 多方块结构模块 - Patchouli 风格的结构定义
背景问题
Minecraft 模组中常见的多方块结构(如祭坛、多方块机器)在插件开发中缺乏标准化的定义和验证工具,开发者需要手写大量坐标检查代码。
解决方案
参考 Patchouli 的 Multiblock 设计,提供两种结构定义方式和完整的验证能力。
两种定义方式
密集型(DenseMultiblock)—— 适合紧凑结构:
val altar = DenseMultiblock(
pattern = arrayOf(
arrayOf( // 顶层
" ",
" S ",
" "
),
arrayOf( // 底层
"SSS",
"S0S", // '0' = 中心锚点
"SSS"
)
),
mapping = mapOf(
'S' to StringStateMatcher.parse("minecraft:stone_bricks")
)
)
稀疏型(SparseMultiblock)—— 适合大型不规则结构:
val gate = SparseMultiblock(
blocks = mapOf(
BlockPos(0, 0, 0) to StringStateMatcher.parse("minecraft:obsidian"),
BlockPos(0, 1, 0) to StringStateMatcher.parse("minecraft:obsidian"),
BlockPos(0, 2, 0) to StringStateMatcher.parse("minecraft:obsidian"),
BlockPos(1, 3, 0) to StringStateMatcher.parse("minecraft:obsidian"),
// ...
)
)
核心特性:
- 支持 4 方向旋转检测与对称优化
StateMatcher/StringStateMatcher方块状态匹配器MultiblockRegistry全局注册表- 结构模拟(计算世界坐标,用于预览和进度提示)
4. PlayerFakeOp 全面兼容 - Java 16+ 与 Paper 1.21.8+
背景问题
PlayerFakeOp 在 Java 16+ 和 Paper 1.21.8+ 上存在两个严重问题:
- Java 16 模块系统阻止 ByteBuddy 的 INJECTION 类加载策略
- Paper 1.21.8+ 将命令执行队列化,导致 FakeOp 代理在异步上下文中失效
解决方案
- ByteBuddy 类加载策略从 INJECTION 改为 CHILD_FIRST
- 1.13+ 使用 NMS
CommandSourceStack直接派发,绕过 Paper 命令队列 - 不修改玩家真实 OP 状态
5. PTC Object ORM 架构重构
对 6.2.4 引入的 PTC Object ORM 进行了深度架构重构,引入多种设计模式提升可维护性:
- Template Method:
AbstractDataMapper基类,DataMapperImpl/TransactionalDataMapper仅覆写差异 - Strategy:
DatabaseDialect接口(MySQL/SQLite/PostgreSQL),消除建表逻辑重复 - SRP:
EntityMapper分离 ResultSet 读取与实例创建 - Facade + Composite:
ContainerOperatorImpl拆分为DataExecutor/LinkTableHandler/CollectionTableHandler - 分包:内部实现移至
orm/container/operator/mapper子包,公开 API 保持不变
同时修复了 SQLite 下 @Id 生成 PRIMARY KEY(唯一约束)与 MySQL 端 KEY(非唯一索引)行为不一致的问题。
6. 命令组件描述功能
新增命令帮助系统增强,支持为命令组件添加描述信息,改善玩家使用体验。CommandHelper 模块现在可以自动生成结构化的命令帮助文档。
7. 其他改进
- SNAPSHOT 依赖支持:
PrimitiveLoader现在支持 SNAPSHOT 版本依赖下载和本地仓库 SHA1 生成 - identityLazy / weakIdentityLazy:新增基于对象身份的懒加载委托工具
- AetherResolver 重构:修复依赖注入逻辑,支持 JSON 格式依赖声明
- Reflex 升级至 1.2.4:修复 JDK 8 兼容问题
- FileWatcher 优雅降级:inotify 实例耗尽时不再崩溃,改为降级运行并输出警告
- SnakeYAML 修复:修复 Composer 注释事件导致的 ClassCastException
- Velocity 命令权限:修复命令注册时未处理 permission 权限检查的问题
- ActionPlayer 线程安全:Kether ActionPlayer 现在要求主线程执行
- 1.21+ JSON 合规:JSON 文本组件中禁止包含
§字符 - JDK 8 二次启动修复:回退 Reflex 类缓存为即时扫描,避免 ByteBuffer API 兼容问题
- 旧版依赖处理回退:新增选项强制使用旧版依赖处理工具
迁移指南
从 6.2.x 升级到 6.3.0
6.3.0 是一个大版本更新,但保持了良好的向后兼容性。主要注意事项:
PTC Object 内部包路径变更:
如果你直接引用了 PTC Object 的内部类(如 ContainerSQL、AnalyzedClass),需要更新导入路径:
// 迁移前
import taboolib.expansion.ContainerSQL
import taboolib.expansion.AnalyzedClass
// 迁移后
import taboolib.expansion.container.ContainerSQL
import taboolib.expansion.orm.AnalyzedClass
公开 API(DataMapper、mapper 委托、注解等)保持不变,无需修改。
SQLite @Id 行为变更:
SQLite 下 @Id 不再生成 PRIMARY KEY(唯一约束),改为普通索引,与 MySQL 行为对齐。如果你依赖了旧的唯一约束行为,需要额外添加 @Key 注解。
使用 Incision 模块
添加依赖:
compileOnly(project(":module:incision"))
使用多方块结构模块
添加依赖:
compileOnly(project(":module:minecraft:minecraft-multiblocks"))
文档更新
本次更新同步更新了以下文档:
- Minecraft 26.1.2 附魔链路分析:基于 NMS 源码的附魔系统完整链路分析,覆盖附魔写入、运行时计算、效果组件等全部链路
致谢
感谢以下贡献者为本次更新做出的贡献:
- @Micalhl - Minecraft 26.1 全面适配(17 个提交)、NMS 转译逻辑重写、Reflex 升级、虚拟界面升级、Packet#nameInMojang
- @Ray_Hughes - Incision 字节码织入模块、多方块结构模块、PTC Object 架构重构
- @黑 - Reflex 升级、identityLazy 工具、SQLite @Id 修复、Velocity 命令权限、虚拟背包适配、SnakeYAML 修复、ActionPlayer 线程安全、RemoteQuestContext 修复
- @wxys233 - 命令组件描述功能、SNAPSHOT 依赖支持
- @Jie-150 - 1.21+ JSON 合规、版本号获取改进、回调函数改进
- @dakuo - PlayerFakeOp 全面兼容 Java 16+ 和 Paper 1.21.8+
- @Score2 - FileWatcher 优雅降级
- @White_Souls - JDK 8 二次启动修复
- @蛟龙 - AetherResolver 依赖注入重构
如有问题或建议,欢迎在 GitHub Issues 反馈。