括号语法
基本信息
| 属性 | 值 |
|---|---|
| 处理器数量 | 4(全部 @BracketHandler) |
| 分发方式 | 按注册顺序遍历,第一个返回非 null 的胜出(GlobalRegistry.java:111-120) |
| 解析入口 | GlobalRegistry.resolveBracket ← MyCompileEnvironment.getBracketed(GlobalRegistry.java:211-214) |
| 优先级 | 仅 ItemBracketHandler 声明 priority = 100(ItemBracketHandler.java:39) |
| 1.7.10 实现 | mc1710/brackets/ 3 个 + mods/ic2/IC2BracketHandler.java 1 个 |
括号语法是脚本里 <...> 形式的字面量。它在编译期由 getBracketed 拦截,不走 ZenScript 常规的标识符/字符串词法,因此这些名字不需要加引号。
| 处理器 | 脚本名 | 文件 | 门控 | 优先级 |
|---|---|---|---|---|
| 物品 | 无前缀 | mc1710/brackets/ItemBracketHandler.java:39-40 |
无 | 100 |
| 流体 | <liquid:...> |
mc1710/brackets/LiquidBracketHandler.java:30-31 |
无 | 默认 |
| 矿物 | <ore:...> |
mc1710/brackets/OreBracketHandler.java:32-33 |
无 | 默认 |
| IC2 物品 | <ic2-item:...> |
mods/ic2/IC2BracketHandler.java:33-35 |
@ModOnly("IC2") |
默认 |
@BracketHandler(priority = 100) 的 priority 字段从未被任何代码读取。字段定义在 minetweaker/annotations/BracketHandler.java:24(default 10),其 javadoc 写明 “A lower value means a higher priority. Only change if you have issues”(:19),但 GlobalRegistry.resolveBracket 只是朴素顺序遍历(GlobalRegistry.java:111-120),registerBracketHandler 也只是 list.add(GlobalRegistry.java:83-85)。全仓 grep -rn priority src/main/java buildSrc/src 仅命中该注解定义、ItemBracketHandler 的使用点,以及一条无关的日志级别注释(MineTweakerAPI.java:169)。因此当前 4 个处理器的实际生效顺序取决于类注册顺序,而不是声明的优先级。
物品:<Name> / <*> / <item:Name> / <Name:meta> / <Name:*>
ItemBracketHandler.resolve(ItemBracketHandler.java:71-102)按顺序判定:
| 写法 | 触发条件 | 结果 | 源码行 |
|---|---|---|---|
<*> |
token 数恰为 1 且值为 * |
IngredientAny.INSTANCE 单例符号 |
:74-76 |
<item:Name> |
token 数 > 2 且前两个是 item : |
跳过前 2 个 token 再拼接 | :87-89 |
<Name:meta> |
token 数 > 2 且末两是 : + 整数值 |
meta = 该整数 |
:90-93 |
<Name:*> |
token 数 > 2 且末两是 : * |
meta = OreDictionary.WILDCARD_VALUE(32767) |
:94-98 |
<Name> |
其余情况,从 0 拼到末尾 | meta = 0 |
:82-84、:101 |
名称表在加载完成时重建:rebuildItemRegistry() 遍历 Item.itemRegistry.getKeys(),把注册名中的空格与撇号删除后作键(ItemBracketHandler.java:45-51)。所以 <Iron Ingot> 与 <IronIngot> 等价,<Diamond Sword> 等价于 <DiamondSword>。
拼不到名字时 find 返回 null(ItemBracketHandler.java:113-117),交由下一个处理器;4 个处理器都不认才报错。
meta 缺省为 0,最终统一走 getIItemStackWildcardSize(item, meta)(ItemBracketHandler.java:57)。
流体:<liquid:Name>
LiquidBracketHandler.resolve(LiquidBracketHandler.java:52-61)要求 token 数 > 2 且前两个恰为 liquid :,否则直接返回 null —— 即无前缀的裸名称不会被当作流体。
流体表同样去空格:rebuildLiquidRegistry() 把 FluidRegistry.getRegisteredFluids() 的键去掉空格(LiquidBracketHandler.java:36-40)。命中后返回 new MCLiquidStack(new FluidStack(fluid, 1))(:46),数量固定为 1,<liquid:Water> 本身不带数量,数量要用后续方法调整。
矿物:<ore:Name>
OreBracketHandler.resolve(OreBracketHandler.java:53-62)结构与流体一致,要求 ore : 前缀。
与流体不同,getOre 永不返回 null:
public static IOreDictEntry getOre(String name) {
return new MCOreDictEntry(name);
}
(OreBracketHandler.java:34-36)。find 也不查表,直接 new OreReferenceSymbol(...)(OreBracketHandler.java:71)。后果:<ore:完全不存在的名字> 不会报错,会得到一个空条目;删除类配方时要留意这种静默失效。
支持 * 通配:编译成正则,把 * 替换为 .+ 再全表匹配(OreBracketHandler.java:39-49),返回 IOreDictEntry[]。注意 .+ 至少匹配一个字符,故 <ore:*> 不匹配空名。
IC2 物品:<ic2-item:Name[:meta]>
IC2BracketHandler.resolve(IC2BracketHandler.java:50-80)要求 token 数 >= 5 且前四个依次是 ic2 - item ::
| 写法 | 结果 | 源码行 |
|---|---|---|
<ic2-item:Name> |
meta 0 | :55-57 |
<ic2-item:Name:meta> |
整数值作 meta | :58-59 |
<ic2-item:Name:*> |
WILDCARD_VALUE |
:60-61 |
<ic2-item:Name:非法值> |
logError("Not a valid meta value: ..."),meta 保持 0 |
:62-64 |
分隔符是连字符 ic2-item 而非冒号(:52-53),与 <ore:> / <liquid:> 风格不同。
与前三个处理器不同,IC2 这个会主动校验物品是否存在:IC2Items.getItem(name) 为 null 时 logError("Not a valid IC2 item: " + name) 并返回 null(:65-69)。
该处理器带 @ModOnly("IC2")(:34),未装 IC2 时不会被实例化注册。