import { world, system, PlayerSpawnAfterEvent, WatchdogTerminateReason } from "@minecraft/server";1import { shutdownTimers } from "./utils/scheduling.js";2import { shutdownThreads } from "./utils/multithreading.js";3import { RawText } from "./utils/index.js";45// eslint-disable-next-line prefer-const6let _server: ServerBuild;78system.beforeEvents.watchdogTerminate.subscribe((ev) => {9if (ev.terminateReason == WatchdogTerminateReason.Hang) {10ev.cancel = true;11shutdownTimers();12shutdownThreads();13if (_server) _server.shutdown();1415const players = Array.from(world.getPlayers());16if (players.length == 0) {17const event = (ev: PlayerSpawnAfterEvent) => {18if (!ev.initialSpawn) return;19world.afterEvents.playerSpawn.unsubscribe(event);20RawText.translate("script.watchdog.error.hang").print(ev.player);21};22system.run(() => world.afterEvents.playerSpawn.subscribe(event));23} else {24for (const player of players) {25RawText.translate("script.watchdog.error.hang").print(player);26}27}28}29});3031export * from "./utils/index.js";3233import { Player as PlayerBuilder } from "./classes/playerBuilder.js";34import { Command } from "./classes/commandBuilder.js";35import { ServerBuilder } from "./classes/serverBuilder.js";36import { UIForms } from "./classes/uiFormBuilder.js";37import { Block } from "./classes/blockBuilder.js";3839export { CustomArgType, CommandPosition } from "./classes/commandBuilder.js";40export type { commandSyntaxError, registerInformation as CommandInfo } from "./@types/classes/CommandBuilder";41export { Databases } from "./classes/databaseBuilder.js";42export { configuration } from "./configurations.js";4344class ServerBuild extends ServerBuilder {45public block = Block;46public player = PlayerBuilder;47public command = Command;48public uiForms = UIForms;4950constructor() {51super();52this._buildEvent();53this._buildCommands();54}55/**56* @private57*/58private _buildEvent() {59const beforeEvents = world.beforeEvents;60const afterEvents = world.afterEvents;6162beforeEvents.chatSend.subscribe((data) => {63/**64* Emit to 'beforeMessage' event listener65*/66this.emit("beforeMessage", data);67/**68* This is for the command builder and a emitter69*/70const msg = data.message;71if (!msg.startsWith(this.command.prefix)) return;72data.cancel = true;73const command = msg.split(/\s+/)[0].slice(this.command.prefix.length);74try {75this.command.callCommand(data.sender, command, msg.substring(msg.indexOf(command) + command.length).trim());76} catch (e) {77if (e instanceof RawText) e.printError(data.sender);78else RawText.text(e).printError(data.sender);79}80});8182/**83* Emit to 'beforeExplosion' event listener84*/85beforeEvents.explosion.subscribe((data) => this.emit("beforeExplosion", data));86/**87* Emit to 'blockExplode' event listener88*/89afterEvents.blockExplode.subscribe((data) => this.emit("blockExplode", data));90/**91* Emit to 'beforeExplosion' event listener92*/93beforeEvents.explosion.subscribe((data) => this.emit("explosion", data));94/**95* Emit to 'pistonActivate' event listener96*/97afterEvents.pistonActivate.subscribe((data) => this.emit("pistonActivate", data));98/**99* Emit to 'itemUse' event listener100*/101beforeEvents.itemUse.subscribe((data) => this.emit("itemUseBefore", data));102103/**104* Emit to 'itemUseBeforeOn' event listener105*/106beforeEvents.playerInteractWithBlock.subscribe((data) => this.emit("itemUseOnBefore", data));107108/**109* Emit to 'messageCreate' event listener110*/111afterEvents.chatSend.subscribe((data) => this.emit("messageCreate", data));112/**113* Emit to 'entityEffected' event listener114*/115afterEvents.effectAdd.subscribe((data) => this.emit("entityEffected", data));116/**117* Emit to 'weatherChange' event listener118*/119afterEvents.weatherChange.subscribe((data) => this.emit("weatherChange", data));120/**121* Emit to 'blockBreak' event listener122*/123beforeEvents.playerBreakBlock.subscribe((data) => this.emit("blockBreak", data));124/**125* Emit to 'blockHit' event listener126*/127afterEvents.entityHitBlock.subscribe((data) => this.emit("blockHit", data));128/**129* Emit to 'worldInitialize' event listener130*/131afterEvents.worldLoad.subscribe(() => this.emit("ready", { loadTime: tickCount }));132/**133* Emit to 'playerChangeDimension' event listener134*/135afterEvents.playerDimensionChange.subscribe((data) => this.emit("playerChangeDimension", { player: data.player, dimension: data.player.dimension }));136137/**138* Emit to 'entityCreate' event listener139*/140afterEvents.entitySpawn.subscribe((data) => {141if (data.entity?.isValid) this.emit("entityCreate", data);142});143144let tickCount = 0;145let prevTime = Date.now();146system.runInterval(() => {147tickCount++;148149this.emit("tick", {150currentTick: tickCount,151deltaTime: Date.now() - prevTime,152});153154prevTime = Date.now();155});156157/**158* Emit to 'playerSpawn' event listener159*/160afterEvents.playerSpawn.subscribe((data) => {161if (data.initialSpawn) {162this.emit("playerLoaded", data);163}164});165/**166* Emit to 'playerJoin' event listener167*/168afterEvents.playerJoin.subscribe((data) => {169this.emit("playerJoin", { playerName: data.playerName });170});171/**172* Emit to 'playerLeave' event listener173*/174afterEvents.playerLeave.subscribe((data) => {175this.emit("playerLeave", data);176});177}178179private _buildCommands() {180// system.beforeEvents.startup.subscribe((ev) => {181// for (const command of this.command.getAllRegistation()) {182// if (command.name === "help") continue;183// const names = [command.name, ...(command.aliases ?? [])];184// type Parameters = { mandatoryParameters: CustomCommandParameter[]; optionalParameters: CustomCommandParameter[] };185// const usages: Array<[string[], Parameters]> = [];186// const accumulate = (params: Parameters, subs: Array<string>, argDefs: commandArgList, subName = "") => {187// params = { mandatoryParameters: [...params.mandatoryParameters], optionalParameters: [...params.optionalParameters] };188// subs = [...subs];189// let hasSubCommand = false;190// if (subName) subs.push(subName);191// argDefs?.forEach((arg) => {192// if ("subName" in arg) {193// hasSubCommand = true;194// accumulate(params, subs, arg.args, arg.subName);195// } else {196// const list = "default" in arg ? params.optionalParameters : params.mandatoryParameters;197// const types = {198// bool: CustomCommandParamType.Boolean,199// int: CustomCommandParamType.Integer,200// float: CustomCommandParamType.Float,201// string: CustomCommandParamType.String,202// xyz: CustomCommandParamType.Location,203// enum: CustomCommandParamType.Enum,204// }[arg.type];205// let name = arg.name;206// const customEnumValues = this.command.getCustomArgEnums(arg.type);207// if (arg.type === "enum" || customEnumValues) {208// name = `wedit:${name}`;209// try {210// ev.customCommandRegistry.registerEnum(name, (<commandEnum>arg).values ?? customEnumValues);211// } catch {212// if (!customEnumValues) contentLog.warn("Warning: Enum name already exists", name);213// }214// } else {215// name += types === undefined ? `: ${arg.type}` : "";216// }217// list.push({ name, type: types ?? (customEnumValues ? CustomCommandParamType.Enum : CustomCommandParamType.String) });218// }219// });220// if (!hasSubCommand) usages.push([subs, params]);221// };222// accumulate({ mandatoryParameters: [], optionalParameters: [] }, [], this.command.getRegistration(command.name).usage ?? []);223// for (const name of names) {224// for (const [subCommands, params] of usages) {225// ev.customCommandRegistry.registerCommand(226// {227// name: `wedit:${228// name +229// (subCommands.length230// ? subCommands231// .map((sub) => "_" + sub.replace(/^_+|_+$/g, ""))232// .filter((str) => str !== "_")233// .join("")234// : "")235// }`,236// description: command.description,237// permissionLevel: CommandPermissionLevel.Any,238// ...params,239// },240// (origin, ...args) => {241// if (!origin.sourceEntity?.matches({ type: "player" })) return { message: "WorldEdit commands can only be ran by players", status: CustomCommandStatus.Failure };242// this.command.callCommand(243// <Player>origin.sourceEntity,244// command.name,245// args.map((arg) => `${arg}`),246// subCommands247// );248// return { message: "", status: CustomCommandStatus.Success };249// }250// );251// }252// }253// }254// });255}256}257258_server = new ServerBuild();259export const Server = _server;260261262