事件管理器可达性

基本信息

属性 值
全局符号 events(MineTweakerAPI.java:65)
Java 类型 minetweaker.api.event.IEventManager(接口)
1.7.10 实现 minetweaker.api.event.MTEventManager(唯一实例 MineTweakerImplementationAPI.java:553)
接口上的 @ZenClass 无
接口上的 @ZenMethod 无(20 个 on* 全部裸声明)
接口内 ZenScript 注解总数 0

接口全文特征

api/event/IEventManager.java 共 67 行,结构为「20 个 on* 声明 + 一大段注释」:

public interface IEventManager {

    // implemented
    IEventHandle onPlayerCrafted(IEventHandler<PlayerCraftedEvent> ev);

    // implemented
    IEventHandle onPlayerSmelted(IEventHandler<PlayerSmeltedEvent> ev);

    IEventHandle onPlayerChangedDimension(IEventHandler<PlayerChangedDimensionEvent> ev);
    // ... 共 20 个
}
  • 类 javadoc 自称 “37 kinds of event handlers!” 并注明 “NOTE: not all of these are implemented yet, but will be later on.”(:5-11)—— 但实际只有 20 个 on* 声明。
  • 末尾 /* ... */ 块注释(:52-66)列出了另外 19 个已删除的事件方法:onPlayerUseItemStop、onPlayerUseItemFinish、onPlayerChat、onTimerSingle、onTimerRepeat、onEntityJoinWorld、onEntityStruckByLightning、onLivingEnderTeleport、onLivingAttackEvent、onLivingDeathEvent、onLivingJumpEvent、onLivingFallEvent、onLivingHurtEvent、onLivingDeathDropsEvent、onItemTossed、onItemExpired、onMinecartCollision、onMinecartInteract、onCommand。这些是 1.x 时代的事件,2.x 重写后移除,注释即其墓碑。
  • 文件里只有 2 处 // implemented 标记(:14、:17),对应 onPlayerCrafted 与 onPlayerSmelted —— 与玩家事件里「实际触发的 5 个」并不重合(另外 3 个已触发事件没打标),说明这套注释本身也已过时。

未注册带来的后果

MineTweakerAPI.registerClass 只对带 @ZenClass 的类调 GlobalRegistry.registerNativeClass(MineTweakerAPI.java:312-314)。IEventManager 无该注解,因此它的类型与 20 个方法没有进入 ZenScript 的类型注册表。

对比同一 API 包内的相邻类型可以确认这是逐个决定而非风格统一:

类型 @ZenClass 脚本方法注解
IEventHandle 有(api/event/IEventHandle.java:12) @ZenMethod close()
CommandValidators 有(api/server/CommandValidators.java:10) @ZenGetter isOp()
ICommandFunction 有(api/server/ICommandFunction.java:10) 无(execute 裸声明)
IEventManager 无 无
IFormatter 无 无

api/ 下共 12 个接口无 @ZenClass,完整清单见类型系统与扩展。

无法核实的部分

无法核实:脚本里 events.onPlayerCrafted(function) 究竟能否解析、编译通过。

已核实的是本仓事实:IEventManager 未经 registerClass 处理,其类型名未进 root 命名空间,20 个 on* 方法无 @ZenMethod。

无法核实的原因是:ZenScript 1.0.2-GTNH 对未注册 Java 类型(SymbolJavaStaticField 读出的 ZenTypeJava 值)的方法调用解析策略实现在外部仓 GTNewHorizons/ZenScript,本仓只有注解与文档生成器的副本(buildSrc/src/main/java/stanhebben/zenscript/),没有引擎本体。我没有该仓源码,也没有运行环境去实测,因此不对「能用 / 不能用」下结论。

MTEventManager 的实例与门控

MTEventManager 自身是 public static final 单例(MineTweakerImplementationAPI.java:553),在 MineTweakerMod 构造器里通过 init(...) 之外的方式直接暴露为 MineTweakerAPI.events(MineTweakerAPI.java:118):

public static final IEventManager events = MineTweakerImplementationAPI.events;

events 字段是 final 且在 MineTweakerAPI 类初始化时即指向 MineTweakerImplementationAPI 的单例,因此服务器未启动时它也已经非 null —— 与 server / client 这类启动后才赋值的字段不同。脚本在客户端也能安全访问 events,只是不会有事件到达(客户端不跑服务器逻辑)。

registerClassRegistry 的 @ModOnly 门控(MineTweakerAPI.java:245-256)会调用 loadedMods.contains(mod),即依赖 ILoadedMods 的 @ZenOperator(CONTAINS),见Minecraft 层 API。

相关条目