架构设计与 Mixin 解析 (MC 26.2)
本文档深入解析 Minecraft 26.2 上 Item Clumps 的内部包布局、类继承体系、Mixin 注入目标清单与影子成员细节。
🌳 包层级结构与类图
net.instantgratification.item_clumps
│
├── ItemClumpsFabric.java [Main Entrypoint / GameRules Registration]
│
├── config/
│ ├── ItemClumpsConfig.java [Configuration POJO / ConfigHelper Persistence]
│ ├── ModMenuIntegration.java [ModMenuApi Provider / Safe GUI Factory]
│ └── YaclScreenHelper.java [YetAnotherConfigLib v3 Screen Factory]
│
├── mixin/
│ ├── HopperBlockEntityMixin.java [Hopper Drip Extraction Mixin]
│ └── ItemEntityMixin.java [Mega-Stack Aggregation & Smart Pickup Mixin]
│
└── util/
└── ModVersionGuard.java [Knot ClassLoader Runtime Safety Guard]🛠️ 完整 Mixin 目标与注入点详解
1. ItemEntityMixin.java
- 目标类:
net.minecraft.world.entity.item.ItemEntity - 超类继承:
extends net.minecraft.world.entity.Entity
| 成员 / 方法 | 注解 | 注入点 | 用途目的 |
|---|---|---|---|
getItem() | @Shadow | N/A | 访问实体内部的物品堆栈。 |
setItem(ItemStack) | @Shadow | N/A | 修改物品堆栈并同步更新追踪器数据。 |
target | @Shadow | N/A | 目标玩家的 UUID(用于按 Q 投掷安全)。 |
pickupDelay | @Shadow | N/A | 拾取冷却计时器 ticks。 |
age | @Shadow | N/A | 消失年龄计时器 ticks ($0\text{ 至 }6000$)。 |
setItem | @Inject | @At("TAIL") | 物品堆数量变动时触发铭牌更新。 |
isMergable | @Inject | @At("HEAD"), cancellable = true | 将原版最大堆叠检查替换为 max_clump_size 规则。 |
mergeWithNeighbours | @Redirect | INVOKE -> AABB.inflate(DDD) | 零对象分配扩展水平搜索半径 ($r \in [1, 10]$)。 |
tryToMerge | @Inject | @At("HEAD"), cancellable = true | 执行 64 位求和、最年轻年龄继承与磁铁吸附检测。 |
playerTouch | @Inject | @At("HEAD"), cancellable = true | 执行单批次原生存放并拆分为纯原版规格堆叠。 |
2. HopperBlockEntityMixin.java
- 目标类:
net.minecraft.world.level.block.entity.HopperBlockEntity
| 方法 | 注解 | 注入点 | 用途目的 |
|---|---|---|---|
addItem(Container, ItemEntity) | @Inject | @At("HEAD"), cancellable = true | 从巨型聚合体中每次仅抽取 1 个切片 ($2.5\text{ 个/秒}$) 存入漏斗。 |
📄 Mixin 配置文件 (item-clumps.mixins.json)
json
{
"required": true,
"package": "net.instantgratification.item_clumps.mixin",
"compatibilityLevel": "JAVA_25",
"refmap": "item-clumps-refmap.json",
"mixins": [
"HopperBlockEntityMixin",
"ItemEntityMixin"
],
"injectors": {
"defaultRequire": 1
}
}