跳到主要内容

TabooLib 6.3.0 更新 - Incision 字节码织入、Minecraft 26.1 全面适配与多方块结构模块

· 阅读需 14 分钟
TabooLib 开发团队
TabooLib 核心开发者

本次更新标志着 TabooLib 进入 6.3.0 时代,涉及 315 个文件、超过 22000 行新增代码。核心亮点包括全新的 Incision 字节码织入模块、Minecraft 26.1(1.22)全面适配、多方块结构模块、NMS 转译逻辑重写,以及大量兼容性修复和基础设施改进。

涉及的相关提交

Incision 字节码织入模块

  • 53fee236

    feat(incision): 新增字节码织入模块与 Accessor API

    由 @Ray_Hughes 提交 - 全新的运行时织入框架,支持注解和 DSL 双入口

  • 2b33b803

    fix(incision): suppress non-error logs outside debug mode

    由 @Ray_Hughes 提交 - 非调试模式下抑制非错误日志

Minecraft 26.1 全面适配

  • 62ae4bb5

    nms 模块初步兼容 26.1, 更改转译逻辑, 等待修复 bug。

    由 @Micalhl 提交 - NMS 模块初步适配 26.1

  • 0d44585d

    新的转译逻辑,Paper/Spigot 1.20.4、1.21.11、26.1 测试通过

    由 @Micalhl 提交 - 新转译逻辑全版本测试通过

  • 3dc6817f

    新的 reflex 转译逻辑,Paper/Spigot 1.20.4、1.21.11 测试通过

    由 @Micalhl 提交 - Reflex 转译逻辑更新

  • 6e6376bb

    分离 isUniversalCraftBukkit 和 isMojangMapping,在 Paper/Spigot 1.19.4、1.20.4、1.21.11、26.1 上测试通过

    由 @Micalhl 提交 - 映射判断逻辑分离

  • 866c0008

    EntityAI、NMS stable 在 Paper/Spigot 1.21.11、26.1 上通过测试

    由 @Micalhl 提交 - EntityAI 和 NMS stable 模块适配

  • 2a16dbc9

    module-nms 模块全部通过测试

    由 @Micalhl 提交 - NMS 模块全面测试通过

  • 6c4c881b

    ItemTag 测试通过

    由 @Micalhl 提交 - ItemTag 模块适配验证

  • ee8e8695

    navigation 寻路模块通过编译

    由 @Micalhl 提交 - 寻路模块适配

  • b4f97803

    支持 26.1.1,升级虚拟界面模块,并修复与 tb 6.2 插件的兼容性

    由 @Micalhl 提交 - 26.1.1 支持与向后兼容

  • 716e043a

    支持 26.1.2

    由 @Micalhl 提交 - 26.1.2 版本支持

多方块结构模块

  • fcbd090a

    feat(minecraft-multiblocks): 新增多方块结构模块

    由 @Ray_Hughes 提交 - 参考 Patchouli 设计的多方块结构定义与验证

NMS 与数据包改进

  • fd8e4050

    新增 Packet#nameInMojang 字段并在 Paper/Spigot 1.8.8 和 1.21.11 通过测试

    由 @Micalhl 提交 - 数据包 Mojang 名称查询

  • 3f657a61

    将 XSeries 强制编译到 26.1

    由 @Micalhl 提交 - XSeries 版本适配

PTC Object ORM 重构

  • d21632e0

    refactor(database): 重构 ptc-object ORM 模块,拆分子包并消除重复代码

    由 @Ray_Hughes 提交 - 架构重构,引入设计模式

命令系统增强

  • 9e51521c

    feat(command): 添加命令组件描述功能支持

    由 @wxys233 提交 - 命令帮助系统增强

基础设施改进

  • 8626e245

    feat(common): 支持 SNAPSHOT 版本依赖下载和本地仓库 SHA1 生成

    由 @wxys233 提交 - SNAPSHOT 依赖解析

  • 772aae4c

    更新 reflex 到 1.2.3

    由 @黑 提交 - Reflex 库升级

  • 88720d89

    更新 Reflex 至 1.2.4,修复与 JDK 8 的兼容问题

    由 @Micalhl 提交 - Reflex 库再次升级

  • b266e164

    新增 identityLazy 和 weakIdentityLazy 工具

    由 @黑 提交 - 基于身份的懒加载委托

  • 5fe51385

    refactor(AetherResolver): fix dependency injection logic & support for JSON dependency loading

    由 @蛟龙 提交 - 依赖解析器重构

  • 3d340971

    新增一个选项来强制使用旧版依赖处理工具

    由 @Micalhl 提交 - 依赖处理回退选项

  • 5e9c76b1

    调整服务端依赖,更新 servergen 工具

    由 @Micalhl 提交 - 服务端依赖调整

Bug 修复

  • 5b4b708f

    fix: PlayerFakeOp 兼容 Java 16+ 和 Paper 1.21.8+

    由 @dakuo 提交 - FakeOp 全面兼容修复

  • 99d306c9

    fix: 修复 JDK 8 下 TabooLib 二次启动加载异常

    由 @White_Souls 提交 - JDK 8 兼容性修复

  • 1b45e419

    fix(FileWatcher): gracefully handle inotify exhaustion instead of crashing

    由 @Score2 提交 - FileWatcher 优雅降级

  • 02472c24

    fix: SQLite @Id 不再生成 PRIMARY KEY, 改为普通索引

    由 @黑 提交 - SQLite 索引行为与 MySQL 对齐

  • 502985ac

    fix: Velocity 命令注册未处理 permission 权限检查

    由 @黑 提交 - Velocity 命令权限修复

  • c90a2377

    fix: 虚拟背包适配 1.21.8 ClientboundContainerSetContentPacket 构造器变更

    由 @黑 提交 - 虚拟背包高版本适配

  • 16571d59

    fix(yaml): 修复 SnakeYAML Composer 注释事件 ClassCastException

    由 @黑 提交 - YAML 解析异常修复

  • e7fd0434

    修复 spigot 1.21.11 版本号读取异常

    由 @Micalhl 提交

  • 7a0038b4

    1.21+的json禁止包含§字符

    由 @Jie-150 提交 - JSON 文本组件合规

  • 3d808ef5 / 12d6b12b

    改进版本号获取方式,支持spigot-1.21.11的版本号读取

    由 @Jie-150 提交 - XItemStack 版本号获取改进

  • ac708173 / e7a8a039

    增加写入Boolean值回调函数,Bukkit输出不过滤null值 / 回调输出过滤null值

    由 @Jie-150 提交 - 回调函数与输出过滤改进

  • a3e8abbb

    修复 RemoteQuestContext#setExitStatus 逻辑异常

    由 @黑 提交

  • fbd7e1ba / 73b3d27b

    ActionPlayer 要求主线程执行

    由 @黑 提交 - Kether ActionPlayer 线程安全修复

一句话简述更新

Incision 织入框架让插件拥有手术刀级别的字节码能力,Minecraft 26.1 全线适配为新版本保驾护航。

本次更新的重点

1. Incision 字节码织入模块 - 手术式运行时织入

背景问题

Bukkit/Paper 插件开发中,经常需要修改服务端或其他插件的行为:Hook 方法入口/出口、替换调用点、注入诊断逻辑。传统方案要么依赖重量级的 Mixin 框架,要么手写 ASM 字节码,门槛高且难以维护。

解决方案

Incision 提供一套可控、可诊断、可回滚的手术式织入能力,同时支持注解和 DSL 两种入口,在 LifeCycle.CONST 阶段完成物理织入,运行时零额外开销。

架构总览

核心能力

注解模式(推荐用于长期稳定 patch):

ExampleSurgeon.kt
@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):

DynamicPatch.kt
// 作用域内生效,离开自动回滚
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 自动降级:

  1. JVMTI Native(C 原生库)—— 最强能力,支持已加载类的重定义
  2. Instrumentation(Java Agent)—— 标准 Agent 方式
  3. ClassLoader Hook —— 兜底方案,拦截类加载

NMS 版本门控

Incision 与 TabooLib 的 NMS remap 系统深度集成:

NmsPatch.kt
@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 上全部测试通过
  • 映射判断分离:将 isUniversalCraftBukkitisMojangMapping 拆分为独立判断,解决 26.1 下两者不再等价的问题
  • Reflex 转译更新:配合 Reflex 1.2.3 → 1.2.4 升级,修复反射调用在新版本下的兼容性
  • 虚拟界面升级:适配 ClientboundContainerSetContentPacket 构造器变更
  • XSeries 强制编译到 26.1:确保物品、粒子、音效等工具类支持新版本
  • Packet#nameInMojang:新增数据包的 Mojang 名称字段,方便调试和版本适配

版本支持矩阵:

模块1.8.81.19.41.20.41.21.1126.126.1.126.1.2
NMS Core
EntityAI-
ItemTag
Navigation-
Virtual UI-

3. 多方块结构模块 - Patchouli 风格的结构定义

背景问题

Minecraft 模组中常见的多方块结构(如祭坛、多方块机器)在插件开发中缺乏标准化的定义和验证工具,开发者需要手写大量坐标检查代码。

解决方案

参考 Patchouli 的 Multiblock 设计,提供两种结构定义方式和完整的验证能力。

两种定义方式

密集型(DenseMultiblock)—— 适合紧凑结构:

DenseExample.kt
val altar = DenseMultiblock(
pattern = arrayOf(
arrayOf( // 顶层
" ",
" S ",
" "
),
arrayOf( // 底层
"SSS",
"S0S", // '0' = 中心锚点
"SSS"
)
),
mapping = mapOf(
'S' to StringStateMatcher.parse("minecraft:stone_bricks")
)
)

稀疏型(SparseMultiblock)—— 适合大型不规则结构:

SparseExample.kt
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+ 上存在两个严重问题:

  1. Java 16 模块系统阻止 ByteBuddy 的 INJECTION 类加载策略
  2. 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 MethodAbstractDataMapper 基类,DataMapperImpl / TransactionalDataMapper 仅覆写差异
  • StrategyDatabaseDialect 接口(MySQL/SQLite/PostgreSQL),消除建表逻辑重复
  • SRPEntityMapper 分离 ResultSet 读取与实例创建
  • Facade + CompositeContainerOperatorImpl 拆分为 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 的内部类(如 ContainerSQLAnalyzedClass),需要更新导入路径:

// 迁移前
import taboolib.expansion.ContainerSQL
import taboolib.expansion.AnalyzedClass

// 迁移后
import taboolib.expansion.container.ContainerSQL
import taboolib.expansion.orm.AnalyzedClass

公开 API(DataMappermapper 委托、注解等)保持不变,无需修改。

SQLite @Id 行为变更:

SQLite 下 @Id 不再生成 PRIMARY KEY(唯一约束),改为普通索引,与 MySQL 行为对齐。如果你依赖了旧的唯一约束行为,需要额外添加 @Key 注解。

使用 Incision 模块

添加依赖:

compileOnly(project(":module:incision"))

使用多方块结构模块

添加依赖:

compileOnly(project(":module:minecraft:minecraft-multiblocks"))

文档更新

本次更新同步更新了以下文档:

致谢

感谢以下贡献者为本次更新做出的贡献:

  • @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 反馈。