117 lines
4.3 KiB
JavaScript
117 lines
4.3 KiB
JavaScript
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);
|
|
}
|
|
} |