import { CustomCommandParamType, CustomCommandSource, CustomCommandStatus, Player, RawMessageError, system } from "@minecraft/server"; import { Commands } from "./Commands.js"; import { BlockCommandOrigin } from "./BlockCommandOrigin"; import { EntityCommandOrigin } from "./EntityCommandOrigin"; import { ServerCommandOrigin } from "./ServerCommandOrigin"; import { PlayerCommandOrigin } from "./PlayerCommandOrigin"; import { PACK_IDENTIFIER } from "../../consts.js"; export class Command { customCommand; static resolveCommandOrigin(origin) { switch (origin.sourceType) { case CustomCommandSource.Block: return new BlockCommandOrigin(origin); case CustomCommandSource.Entity: if (origin.sourceEntity instanceof Player) return new PlayerCommandOrigin(origin); return new EntityCommandOrigin(origin); case CustomCommandSource.Server: return new ServerCommandOrigin(origin); default: throw new Error("Unknown command source: " + origin?.sourceType); } } constructor(customCommand) { this.customCommand = customCommand; this.#setDefaultArgs(); Commands.register(this); system.beforeEvents.startup.subscribe(this.setupForRegistry.bind(this)); } getName() { return this.customCommand.name.replace(/^[^:]+:/, ''); } isCheatsRequired() { return this.customCommand.cheatsRequired; } setupForRegistry(startupEvent) { this.#registerCommand(startupEvent.customCommandRegistry); system.beforeEvents.startup.unsubscribe(this.setupForRegistry.bind(this)); } #registerCommand(customCommandRegistry) { this.#addPreCallback(); this.#registerEnums(customCommandRegistry); this.#registerSingleCommand(customCommandRegistry); this.#registerAliasCommands(customCommandRegistry); } #setDefaultArgs() { if (this.customCommand.cheatsRequired === void 0) this.customCommand.cheatsRequired = false; } #addPreCallback() { this.callback = (origin, ...args) => { const source = Command.resolveCommandOrigin(origin); if (this.#commandSourceIsNotAllowed(source)) return { status: CustomCommandStatus.Failure, message: 'construct.error.invalidCommandSource' }; try { return this.customCommand.callback(source, ...args); } catch (error) { if (error instanceof RawMessageError) error.sendTo(source); else throw error; } } } #registerEnums(customCommandRegistry) { if (this.customCommand.enums) { for (const customEnum of this.customCommand.enums) customCommandRegistry.registerEnum(`${PACK_IDENTIFIER}:${customEnum.name}`, customEnum.values); } } #registerSingleCommand(customCommandRegistry, name = this.customCommand.name) { customCommandRegistry.registerCommand({ name: `${PACK_IDENTIFIER}:${name}`, description: this.customCommand.description, permissionLevel: this.customCommand.permissionLevel, mandatoryParameters: this.#prepParameters(this.customCommand.mandatoryParameters), optionalParameters: this.#prepParameters(this.customCommand.optionalParameters), cheatsRequired: this.customCommand.cheatsRequired }, this.callback); } #prepParameters(parameters) { if (!parameters) return []; for (const parameter of parameters) { if (parameter.name) parameter.name = `${parameter.name}`; if (parameter.type === CustomCommandParamType.Enum) parameter.name = `${PACK_IDENTIFIER}:${parameter.name}`; } return parameters; } #registerAliasCommands(customCommandRegistry) { if (this.customCommand.aliases) { for (const alias of this.customCommand.aliases) this.#registerSingleCommand(customCommandRegistry, alias); } } #commandSourceIsNotAllowed(source) { if (!this.customCommand.allowedSources) return false; return !this.customCommand.allowedSources.includes(source.constructor); } }