Path: blob/master/src/library/classes/serverBuilder.ts
1784 views
import { world, Player, Entity, Dimension, CommandResult } from "@minecraft/server";1import { EventEmitter } from "./eventEmitter.js";2import { runCommandReturn } from "../@types/classes/ServerBuilder";3import { sleep } from "@notbeer-api";4import { EventList } from "library/@types/Events.js";56export class ServerBuilder extends EventEmitter<EventList> {7private commandQueue: Promise<runCommandReturn>[] = [];8private flushingCommands = false;910/**11* Force shuts down the server12* @example ServerBuilder.close()13*/14close(): void {15function crash() {16// eslint-disable-next-line no-constant-condition17while (true) {18crash();19}20}21crash();22}2324/**25* Run a command in game26* @param command The command you want to run27* @returns {runCommandReturn}28* @example ServerBuilder.runCommand('say Hello World!');29*/30runCommand(command: string, target?: Dimension | Player | Entity): runCommandReturn {31try {32const successCount = (target ?? world.getDimension("overworld")).runCommand(command).successCount;33return { error: false, successCount };34} catch (e) {35return { error: true, successCount: 0 };36}37}3839/**40* Queue a command in game41* @param command The command you want to run at some point42* @returns {Promise<runCommandReturn>}43* @example ServerBuilder.queueCommand('say Hello World!');44*/45queueCommand(command: string, target?: Dimension | Player | Entity): Promise<runCommandReturn> {46try {47if (this.flushingCommands || this.commandQueue.length > 128) throw "queue";4849const promise = new Promise<CommandResult>((resolve) => {50resolve((target ?? world.getDimension("overworld")).runCommand(command));51})52.then((result) => {53return { error: false, ...result };54})55.catch((result) => {56return { error: true, successCount: 0, ...result };57})58.finally(() => this.commandQueue.splice(this.commandQueue.indexOf(promise), 1));59this.commandQueue.push(promise);60return promise;61} catch (e) {62if (typeof e == "string" && e.includes("queue")) {63return (async () => {64await sleep(1);65return await this.queueCommand(command, target);66})();67} else {68return Promise.resolve({ error: true, successCount: 0 });69}70}71}7273/**74* Flushes all pending commands in the current tick.75* Any attempts at running commands while flushing will be queued.76*/77async flushCommands() {78if (this.commandQueue) return;79this.flushingCommands = true;80await Promise.all(this.commandQueue);81this.flushingCommands = false;82}83}84export const Server = new ServerBuilder();858687