UNPKG

yoni-mcscripts-lib

Version:

为 Minecraft Script API 中的部分接口创建了 wrapper,并提供简单的事件管理器和任务管理器,另附有一些便于代码编写的一些小工具。

91 lines (90 loc) 3.72 kB
import { Minecraft } from "../../basis.js"; import { EventRegistry } from "../EventRegistry.js"; import { EventSignalListeningAdapter } from "../adapting/EventSignalListeningAdapter.js"; import { logger } from "../logger.js"; const { world, system } = Minecraft; const VanillaBeforeEvents = world.beforeEvents; const VanillaAfterEvents = world.afterEvents; const SystemBeforeEvents = system.beforeEvents; const SystemAfterEvents = system.afterEvents; export function registerMinecraftNativeEvents() { const eventSignals = { "VanillaEvents": new Set(), "SystemEvents": new Set(), }; for (const propKey in SystemAfterEvents) { //@ts-ignore eventSignals.SystemEvents.add(SystemAfterEvents[propKey]); } for (const propKey in SystemBeforeEvents) { //@ts-ignore eventSignals.SystemEvents.add(SystemBeforeEvents[propKey]); } for (const propKey in VanillaAfterEvents) { //@ts-ignore eventSignals.VanillaEvents.add(VanillaAfterEvents[propKey]); } for (const propKey in VanillaBeforeEvents) { //@ts-ignore eventSignals.VanillaEvents.add(VanillaBeforeEvents[propKey]); } const NotAEventClassNames = [ "BlockEvent", "MessageReceiveAfterEvent" ]; const DefinedEventClassMappings = new Map([ [Minecraft.ItemDefinitionTriggeredAfterEvent, Minecraft.ItemDefinitionAfterEventSignal], [Minecraft.ItemDefinitionTriggeredBeforeEvent, Minecraft.ItemDefinitionBeforeEventSignal], [Minecraft.MessageReceiveAfterEvent, Minecraft.ServerMessageAfterEventSignal] ]); const EventClasses = []; for (const name in Minecraft) { if (!name.endsWith("Event") || NotAEventClassNames.includes(name)) continue; const clazz = Minecraft[name]; if (typeof clazz !== "function") { throw new TypeError("event " + name + " is not a function"); } const signalName = name + "Signal"; let signalClass = DefinedEventClassMappings.get(clazz) ?? Minecraft[signalName]; if (typeof signalClass !== "function") { throw new TypeError("event signal " + signalName + " is not a function"); } EventClasses.push([name, clazz, signalClass]); } const mappedEventInfos = []; for (const eventClassEntry of EventClasses) { const [name, eventClass, signalClass] = eventClassEntry; let prefixKey = null; let eventSignal = null; FindPrefixAndSignalCode: for (const prefix in eventSignals) { //@ts-ignore const signals = eventSignals[prefix]; for (const signal of signals) { if (Object.getPrototypeOf(signal) === signalClass.prototype) { eventSignal = signal; prefixKey = prefix; signals.delete(signal); break FindPrefixAndSignalCode; } } } if (eventSignal === null) { throw new TypeError("no match eventSignal for event: " + name); } const fullName = prefixKey + "." + name; const info = { fullName, eventClass, eventSignal }; mappedEventInfos.push(info); } for (const info of mappedEventInfos) { const { fullName, eventClass, eventSignal } = info; const adapter = new EventSignalListeningAdapter(eventSignal); const options = { displayName: fullName, extraOption: false, noExtends: true, listeningAdapter: adapter }; EventRegistry.register(eventClass, options); } logger.trace("{} 个Minecraft事件已注册", mappedEventInfos.length); }