yoni-mcscripts-lib
Version:
为 Minecraft Script API 中的部分接口创建了 wrapper,并提供简单的事件管理器和任务管理器,另附有一些便于代码编写的一些小工具。
91 lines (90 loc) • 3.72 kB
JavaScript
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);
}