黑名单 API
基本信息
| 属性 | 值 |
|---|---|
| API 基类 | buildcraft.oiltweak.api.OilTweakAPI(抽象类) |
| API 单例 | public static OilTweakAPI INSTANCE,在 preInit 里赋为 this |
| 黑名单接口 | ItemBlacklistRegistry(注册 provider、查询) |
| Provider 接口 | ItemBlacklistProvider#isBlacklisted(EntityLivingBase, ItemStack) |
| 内置实现 | DefaultBlacklistProvider、BlacklistRegistry |
| API 标记 | `@API(owner = “OilTweak”, provides = “OilTweakAPI” / "OilTweakAPI |
| 对外暴露方 | BuildCraftOilTweak 继承 OilTweakAPI 并覆写 getItemBlacklistRegistry() |
api 与 api.blacklist 两个包各有一个 package-info.java,
用 cpw.mods.fml.common.API 注解声明所有者为 "OilTweak",
apiVersion = Tags.VERSION(构建期生成的版本常量)。
为什么 API 基类是抽象类
BuildCraftOilTweak 本身 extends OilTweakAPI(BuildCraftOilTweak.java:30),
于是一个 @Mod 类同时充当 API 实例。preInit 里:
itemBlacklistRegistry = new BlacklistRegistry();
itemBlacklistRegistry.registerItemBlacklistProvider(new DefaultBlacklistProvider());
OilTweakAPI.INSTANCE = this;
OilTweakAPI 只有一个抽象方法 getItemBlacklistRegistry(),
BuildCraftOilTweak 直接 return itemBlacklistRegistry;。
⚠️ 字段 INSTANCE 是 public static 且没有 volatile,
其他 mod 必须在 postInit 之后(更稳妥是第一个事件触发后)才访问它——
在 preInit 阶段读会拿到 null。
内置黑名单:末影珍珠
DefaultBlacklistProvider 只有一个判定:
return stack != null && (stack.getItem() == Items.ender_pearl
|| stack.getItem() instanceof ItemEnderPearl);
两个条件是 ||,覆盖原版 Items.ender_pearl 与任何 ItemEnderPearl 子类
(如某些 mod 的自定义末影珍珠)。除末影珍珠外没有别的默认条目。
判定语义
BlacklistRegistry#isBlacklisted 是短路 OR:
for (ItemBlacklistProvider provider : providers) {
if (provider.isBlacklisted(entity, stack)) return true;
}
return false;
任一 provider 返回 true 即整体为黑名单。entity 参数原样透传,
留给 provider 自行判断(内置实现不用它)。
注册时 if (provider != null) 过滤空引用;重复注册同一实例不去重。
消费点只有一处
黑名单只被交互限制的右键规则 B 读取:
|| OilTweakAPI.INSTANCE.getItemBlacklistRegistry().isBlacklisted(player, player.getCurrentEquippedItem())
它与"浸没等级"是 || 关系,且外层已要求 inOil.halfOfFull()——
所以离开油中时黑名单完全不生效,黑名单不是无条件禁用末影珍珠。
API 的两个调用时机约束
OilTweakAPI.INSTANCE在preInit才被赋值—— 其他 mod 在自己的preInit(若早于本 mod)访问会拿到null;getItemBlacklistRegistry()返回的是preInit里创建的单个实例, 其他 mod 注册的 provider 会真正生效(列表可变,非不可变视图)。
deInit(FMLModDisabledEvent)里不会清空 provider 列表,
但由于 canBeDeactivated = true,mod 被禁用后 INSTANCE 仍指向旧实例——
onRightClick 里的 OilTweakAPI.INSTANCE 在 mod 被禁用后不再被调用
(事件处理器已 unregister),所以不构成问题。
相关条目
- 交互限制 - 唯一的消费点
- 油液检测 -
isOilDense决定黑名单是否被查询 - Simply Jetpacks 集成 - 另一处
deInit路径