Archived
removed old CommandManager
This commit is contained in:
1 parent
2c31443a01
commit
0ec0eb985b
3 files changed
+17
-328
No files matched your search
@@ -1,312 +0,0 @@
|
|||||||
import axios from "axios";
|
|
||||||
import { CommandInteraction, Message } from "discord.js";
|
|
||||||
import { BaseCommand } from "../structures/BaseCommand.js";
|
|
||||||
import { MissingParameterError } from "../errors.js";
|
|
||||||
import { BooleanParameter, InputParameter, NumberParameter, ObjectParameter, StringParameter } from "../structures/Parameter.js";
|
|
||||||
import { ChatCommand } from "../structures/ChatCommand.js";
|
|
||||||
import { CommandMessageStructure } from "../types/ChatCommand.js";
|
|
||||||
import { applicationState } from "../state.js";
|
|
||||||
import { MessageCommand } from "../structures/MessageCommand.js";
|
|
||||||
import { CommandType, PhraseOccurrenceData } from "../types/BaseCommand.js";
|
|
||||||
import { UserCommand } from "../structures/UserCommand.js";
|
|
||||||
import { CommandResolvable, CommandStructure } from "../types/commands.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @class Command manager
|
|
||||||
*/
|
|
||||||
export class CommandManager {
|
|
||||||
private readonly _chatCommandsList: ChatCommand[] = [];
|
|
||||||
private readonly _messagesCommandsList: MessageCommand[] = [];
|
|
||||||
private readonly _userCommandsList: UserCommand[] = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prefix used as a way to trigger the bot using messages
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
public readonly prefix?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Separator used to split user input to a list of {@link InputParameter}s (applies to prefix interactions)
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
public readonly parameterSeparator: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @constructor
|
|
||||||
* @param {string} [prefix] - prefix used as a way to trigger the bot using messages
|
|
||||||
* @param {string} parameterSeparator - used to split user input to a list of {@link InputParameter}s (applies to prefix interactions)
|
|
||||||
*/
|
|
||||||
constructor(prefix?: string, parameterSeparator?: string) {
|
|
||||||
this.prefix = prefix;
|
|
||||||
this.parameterSeparator = parameterSeparator || ",";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the command by name, alias or keyword
|
|
||||||
* @param {string} phrase - command name, alias or keyword
|
|
||||||
* @returns {ChatCommand | MessageCommand | UserCommand | null} Retrieved extension of {@link BaseCommand} object from the manager or *null*
|
|
||||||
*/
|
|
||||||
public get<T extends CommandType>(phrase: string, type: T): CommandStructure<T> | null {
|
|
||||||
let command: CommandStructure<T> | null = null;
|
|
||||||
switch (type) {
|
|
||||||
case "CHAT":
|
|
||||||
command = (this._chatCommandsList.find((c) => c.name === phrase) as CommandStructure<T>) || null;
|
|
||||||
if (!command) {
|
|
||||||
this._chatCommandsList.map((c) => {
|
|
||||||
if (c.aliases) {
|
|
||||||
c.aliases.map((a) => {
|
|
||||||
if (a === phrase) {
|
|
||||||
command = c as CommandStructure<T>;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "MESSAGE":
|
|
||||||
command = (this._messagesCommandsList.find((c) => c.name === phrase) as CommandStructure<T>) || null;
|
|
||||||
break;
|
|
||||||
case "USER":
|
|
||||||
command = (this._userCommandsList.find((c) => c.name === phrase) as CommandStructure<T>) || null;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return command;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {CommandType} filter - type of commands included in the list
|
|
||||||
* @returns {BaseCommand[]} List of commands registered in the manager
|
|
||||||
*/
|
|
||||||
public getList<T extends CommandType>(filter?: T): readonly CommandStructure<T>[] {
|
|
||||||
switch (filter) {
|
|
||||||
case "CHAT":
|
|
||||||
return Object.freeze([...this._chatCommandsList]) as readonly CommandStructure<T>[];
|
|
||||||
case "MESSAGE":
|
|
||||||
return Object.freeze([...this._messagesCommandsList]) as readonly CommandStructure<T>[];
|
|
||||||
case "USER":
|
|
||||||
return Object.freeze([...this._userCommandsList]) as readonly CommandStructure<T>[];
|
|
||||||
default:
|
|
||||||
return Object.freeze([...this._chatCommandsList, ...this._messagesCommandsList, ...this._userCommandsList]) as CommandStructure<T>[];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds the given {@link Command} to the instance manager with initial processing
|
|
||||||
* @param {BaseCommand} command - {@link Command} instance object
|
|
||||||
* @returns {boolean} Whether this command has been added successfully
|
|
||||||
*/
|
|
||||||
public add(command: CommandResolvable): void {
|
|
||||||
try {
|
|
||||||
if (applicationState.running) {
|
|
||||||
throw new Error("Cannot add a command while the application is running");
|
|
||||||
}
|
|
||||||
if (command instanceof ChatCommand) {
|
|
||||||
const nameOccurrence: PhraseOccurrenceData | null = this.findPhraseOccurrence(command.type, command.name);
|
|
||||||
if (nameOccurrence) {
|
|
||||||
throw new Error(`The name "${command.name}" has already been registered as ${nameOccurrence.type} in the "${nameOccurrence.command.name}" command.`);
|
|
||||||
}
|
|
||||||
command.aliases &&
|
|
||||||
command.aliases.map((a, i, ar) => {
|
|
||||||
const aliasOccurrence: PhraseOccurrenceData | null = this.findPhraseOccurrence(command.type, a);
|
|
||||||
if (aliasOccurrence) {
|
|
||||||
console.warn(
|
|
||||||
`[⚠ WARN] The name "${a}" is already registered as ${aliasOccurrence.type} in the "${aliasOccurrence.command.name}" command. It will be removed from the "${command.name}" command.`
|
|
||||||
);
|
|
||||||
ar.splice(i, 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
command.parameters &&
|
|
||||||
command.parameters.map((p) => {
|
|
||||||
if (p.type != "string" && p.choices) {
|
|
||||||
throw new Error('Parameter with defined choices must have a "string" type');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this._chatCommandsList.push(command);
|
|
||||||
} else if (command instanceof MessageCommand) {
|
|
||||||
const nameOccurrence = this.findPhraseOccurrence(command.type, command.name);
|
|
||||||
if (nameOccurrence) {
|
|
||||||
throw new Error(`The name "${command.name}" has already been registered as ${nameOccurrence.type} in the "${nameOccurrence.command.name}" command.`);
|
|
||||||
}
|
|
||||||
this._messagesCommandsList.push(command);
|
|
||||||
} else if (command instanceof UserCommand) {
|
|
||||||
const nameOccurrence = this.findPhraseOccurrence(command.type, command.name);
|
|
||||||
if (nameOccurrence) {
|
|
||||||
throw new Error(`The name "${command.name}" has already been registered as ${nameOccurrence.type} in the "${nameOccurrence.command.name}" command.`);
|
|
||||||
}
|
|
||||||
this._userCommandsList.push(command);
|
|
||||||
} else {
|
|
||||||
throw new TypeError("Invalid argument type");
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error(`[❌ ERROR] ${e}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers commands from a manager in the Discord API
|
|
||||||
*
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
public async register(applicationId: string, token: string) {
|
|
||||||
const globalList = [
|
|
||||||
...this._chatCommandsList.filter((c) => (!Array.isArray(c.guilds) || c.guilds.length === 0) && c.slash).map((c) => c.toObject()),
|
|
||||||
...this._messagesCommandsList.filter((c) => !Array.isArray(c.guilds) || c.guilds.length === 0).map((c) => c.toObject()),
|
|
||||||
...this._userCommandsList.filter((c) => !Array.isArray(c.guilds) || c.guilds.length === 0).map((c) => c.toObject()),
|
|
||||||
];
|
|
||||||
await axios.put(`https://discord.com/api/v8/applications/${applicationId}/commands`, globalList, { headers: { Authorization: `Bot ${token}` } });
|
|
||||||
}
|
|
||||||
|
|
||||||
public fetch(i: Message | CommandInteraction): CommandMessageStructure | null {
|
|
||||||
if (i instanceof Message) {
|
|
||||||
if (!this.prefix) return null;
|
|
||||||
if (!i.author.bot && i.content.startsWith(this.prefix)) {
|
|
||||||
const content = i.content.replace(this.prefix, "");
|
|
||||||
const name = content.split(" ")[0];
|
|
||||||
const command = this.get(name, "CHAT");
|
|
||||||
if (command) {
|
|
||||||
const argumentsText = content.replace(name, "");
|
|
||||||
const paramsList = argumentsText.split(this.parameterSeparator).map((a) => {
|
|
||||||
return a.replace(" ", "");
|
|
||||||
});
|
|
||||||
if ((paramsList[0] == "" || paramsList[0] == " ") && paramsList.length == 1) {
|
|
||||||
paramsList.splice(0, 1);
|
|
||||||
}
|
|
||||||
const parameters: InputParameter[] = [];
|
|
||||||
command instanceof ChatCommand &&
|
|
||||||
command.parameters.map((p, i) => {
|
|
||||||
if (!p.optional && !paramsList[i]) {
|
|
||||||
throw new MissingParameterError(p);
|
|
||||||
} else if (p.optional && !paramsList[i]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (p.type) {
|
|
||||||
case "mentionable":
|
|
||||||
case "channel":
|
|
||||||
case "role":
|
|
||||||
case "user":
|
|
||||||
parameters.push(new ObjectParameter(p, paramsList[i]));
|
|
||||||
break;
|
|
||||||
case "string":
|
|
||||||
parameters.push(new StringParameter(p, paramsList[i]));
|
|
||||||
break;
|
|
||||||
case "boolean":
|
|
||||||
parameters.push(new BooleanParameter(p, paramsList[i]));
|
|
||||||
break;
|
|
||||||
case "number":
|
|
||||||
parameters.push(new NumberParameter(p, paramsList[i]));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
parameters.push(new InputParameter(p, paramsList[i]));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return {
|
|
||||||
command: command,
|
|
||||||
parameters: parameters,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} else if (i instanceof CommandInteraction) {
|
|
||||||
let cmd: BaseCommand | null = null;
|
|
||||||
if (i.isContextMenu()) {
|
|
||||||
cmd = this.get(i.commandName, i.targetType);
|
|
||||||
} else {
|
|
||||||
cmd = this.get(i.commandName, "CHAT");
|
|
||||||
}
|
|
||||||
if (cmd) {
|
|
||||||
if (i.options?.data) {
|
|
||||||
const paramsList = i.options.data;
|
|
||||||
const parameters: InputParameter[] = [];
|
|
||||||
cmd instanceof ChatCommand &&
|
|
||||||
cmd.parameters.map((p) => {
|
|
||||||
const inputParam = paramsList.find((d) => d.name == p.name);
|
|
||||||
if (!p.optional && !inputParam) {
|
|
||||||
throw new MissingParameterError(p);
|
|
||||||
} else if (p.optional && !inputParam) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (p.type) {
|
|
||||||
case "mentionable":
|
|
||||||
case "channel":
|
|
||||||
case "role":
|
|
||||||
case "user":
|
|
||||||
parameters.push(new ObjectParameter(p, inputParam?.value));
|
|
||||||
break;
|
|
||||||
case "string":
|
|
||||||
parameters.push(new StringParameter(p, inputParam?.value));
|
|
||||||
break;
|
|
||||||
case "boolean":
|
|
||||||
parameters.push(new BooleanParameter(p, inputParam?.value));
|
|
||||||
break;
|
|
||||||
case "number":
|
|
||||||
parameters.push(new NumberParameter(p, inputParam?.value));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
parameters.push(new InputParameter(p, inputParam?.value));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return {
|
|
||||||
command: cmd,
|
|
||||||
parameters: parameters,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private findPhraseOccurrence(type: CommandType, phrase?: string): PhraseOccurrenceData | null {
|
|
||||||
let returnValue: PhraseOccurrenceData | null = null;
|
|
||||||
switch (type) {
|
|
||||||
case "CHAT":
|
|
||||||
this._chatCommandsList.map((c) => {
|
|
||||||
if (phrase == c.name) {
|
|
||||||
returnValue = {
|
|
||||||
command: c,
|
|
||||||
type: "NAME",
|
|
||||||
};
|
|
||||||
} else if (c.aliases && c.aliases.indexOf(phrase || "") != -1) {
|
|
||||||
returnValue = {
|
|
||||||
command: c,
|
|
||||||
type: "ALIAS",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case "MESSAGE":
|
|
||||||
this._messagesCommandsList.map((c) => {
|
|
||||||
if (phrase == c.name) {
|
|
||||||
returnValue = {
|
|
||||||
command: c,
|
|
||||||
type: "NAME",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case "USER":
|
|
||||||
this._userCommandsList.map((c) => {
|
|
||||||
if (phrase == c.name) {
|
|
||||||
returnValue = {
|
|
||||||
command: c,
|
|
||||||
type: "NAME",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+13
-12
@@ -2,7 +2,7 @@ import { Client, CommandInteraction, GuildMember, Intents, Message } from "disco
|
|||||||
import { EventEmitter } from "events";
|
import { EventEmitter } from "events";
|
||||||
import * as http from "http";
|
import * as http from "http";
|
||||||
import { ChatCommand } from "./ChatCommand.js";
|
import { ChatCommand } from "./ChatCommand.js";
|
||||||
import { CommandManager } from "../managers/CommandManager.old.js";
|
import { ChatCommandManager } from "../managers/ChatCommandManager.js";
|
||||||
import { OperationSuccess, PermissionsError } from "../errors.js";
|
import { OperationSuccess, PermissionsError } from "../errors.js";
|
||||||
import { HelpMessage } from "./Help.js";
|
import { HelpMessage } from "./Help.js";
|
||||||
import { SystemMessageManager } from "../managers/SystemMessage.js";
|
import { SystemMessageManager } from "../managers/SystemMessage.js";
|
||||||
@@ -37,9 +37,9 @@ export class Bot extends EventEmitter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Instance command manager
|
* Instance command manager
|
||||||
* @type {CommandManager}
|
* @type {ChatCommandManager}
|
||||||
*/
|
*/
|
||||||
public readonly commands: CommandManager;
|
public readonly chatCommands: ChatCommandManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Discord bot token
|
* Discord bot token
|
||||||
@@ -98,7 +98,7 @@ export class Bot extends EventEmitter {
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
this.commands = new CommandManager(options.prefix, options.parameterSeparator);
|
this.chatCommands = new ChatCommandManager(options.prefix, options.parameterSeparator);
|
||||||
this.token = options.token;
|
this.token = options.token;
|
||||||
this.applicationId = options.applicationId;
|
this.applicationId = options.applicationId;
|
||||||
this.messages = {
|
this.messages = {
|
||||||
@@ -128,7 +128,7 @@ export class Bot extends EventEmitter {
|
|||||||
throw new Error("This bot is already running");
|
throw new Error("This bot is already running");
|
||||||
}
|
}
|
||||||
console.log(`\nBot name: ${this.name}`);
|
console.log(`\nBot name: ${this.name}`);
|
||||||
console.log(`Prefix: ${this.commands.prefix || "/ (only slash commands)"} \n`);
|
console.log(`Prefix: ${this.chatCommands.prefix || "/ (only slash commands)"} \n`);
|
||||||
if (this.token === "") {
|
if (this.token === "") {
|
||||||
throw new ReferenceError('No token specified. Please pass your Discord application token as an argument to the "start" method or in the constructor');
|
throw new ReferenceError('No token specified. Please pass your Discord application token as an argument to the "start" method or in the constructor');
|
||||||
}
|
}
|
||||||
@@ -138,8 +138,8 @@ export class Bot extends EventEmitter {
|
|||||||
console.log("✔");
|
console.log("✔");
|
||||||
}
|
}
|
||||||
if (this.messages.help.enabled === true) {
|
if (this.messages.help.enabled === true) {
|
||||||
const helpMsg: ChatCommand = new HelpMessage(this.commands, this.messages.help, this.name);
|
const helpMsg: ChatCommand = new HelpMessage(this.chatCommands, this.messages.help, this.name);
|
||||||
this.commands.add(helpMsg);
|
this.chatCommands.add(helpMsg);
|
||||||
}
|
}
|
||||||
applicationState.running = true;
|
applicationState.running = true;
|
||||||
process.stdout.write("Connecting to Discord... ");
|
process.stdout.write("Connecting to Discord... ");
|
||||||
@@ -148,8 +148,9 @@ export class Bot extends EventEmitter {
|
|||||||
if (register === undefined || register === true) {
|
if (register === undefined || register === true) {
|
||||||
console.log("✔");
|
console.log("✔");
|
||||||
process.stdout.write(`Registering commands... `);
|
process.stdout.write(`Registering commands... `);
|
||||||
await this.commands.register(this.applicationId, this.token);
|
//await this.chatCommands.register(this.applicationId, this.token);
|
||||||
console.log("✔");
|
//console.log("✔");
|
||||||
|
console.log("❌ [Registration module is not functional in this version]");
|
||||||
} else {
|
} else {
|
||||||
console.log("✔\n");
|
console.log("✔\n");
|
||||||
}
|
}
|
||||||
@@ -158,11 +159,11 @@ export class Bot extends EventEmitter {
|
|||||||
this.client.on("messageCreate", async (m) => {
|
this.client.on("messageCreate", async (m) => {
|
||||||
let cmdMsg: CommandMessageStructure | null = null;
|
let cmdMsg: CommandMessageStructure | null = null;
|
||||||
try {
|
try {
|
||||||
cmdMsg = this.commands.fetch(m);
|
cmdMsg = this.chatCommands.fetch(m);
|
||||||
if (cmdMsg) {
|
if (cmdMsg) {
|
||||||
this.emit("COMMAND", m, cmdMsg);
|
this.emit("COMMAND", m, cmdMsg);
|
||||||
await cmdMsg.command.start(m, cmdMsg.parameters);
|
await cmdMsg.command.start(m, cmdMsg.parameters);
|
||||||
} else if (this.commands.prefix && m.content.startsWith(this.commands.prefix)) {
|
} else if (this.chatCommands.prefix && m.content.startsWith(this.chatCommands.prefix)) {
|
||||||
this.emit("MESSAGE", m);
|
this.emit("MESSAGE", m);
|
||||||
await this.messages.system.send("NOT_FOUND", { phrase: m.content, user: m.member || undefined }, m);
|
await this.messages.system.send("NOT_FOUND", { phrase: m.content, user: m.member || undefined }, m);
|
||||||
} else {
|
} else {
|
||||||
@@ -200,7 +201,7 @@ export class Bot extends EventEmitter {
|
|||||||
let cmd: CommandMessageStructure | null = null;
|
let cmd: CommandMessageStructure | null = null;
|
||||||
try {
|
try {
|
||||||
if (!i.isCommand() && !i.isContextMenu()) return;
|
if (!i.isCommand() && !i.isContextMenu()) return;
|
||||||
cmd = this.commands.fetch(i);
|
cmd = this.chatCommands.fetch(i);
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
this.emit("COMMAND", i, cmd);
|
this.emit("COMMAND", i, cmd);
|
||||||
await cmd.command.start(i, cmd.parameters);
|
await cmd.command.start(i, cmd.parameters);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { MessageEmbed } from "discord.js";
|
import { MessageEmbed } from "discord.js";
|
||||||
import { ChatCommand } from "./ChatCommand.js";
|
import { ChatCommand } from "./ChatCommand.js";
|
||||||
import { CommandManager } from "../managers/CommandManager.old.js";
|
import { ChatCommandManager } from "../managers/ChatCommandManager.js";
|
||||||
import { HelpMessageParams } from "../types/HelpMessage.js";
|
import { HelpMessageParams } from "../types/HelpMessage.js";
|
||||||
|
|
||||||
export class HelpMessage extends ChatCommand {
|
export class HelpMessage extends ChatCommand {
|
||||||
constructor(cmdManager: CommandManager, params: HelpMessageParams, botName?: string) {
|
constructor(cmdManager: ChatCommandManager, params: HelpMessageParams, botName?: string) {
|
||||||
super({
|
super({
|
||||||
name: "help",
|
name: "help",
|
||||||
usage: params.usage,
|
usage: params.usage,
|
||||||
@@ -29,7 +29,7 @@ export class HelpMessage extends ChatCommand {
|
|||||||
helpMsg.setFooter(botName || "");
|
helpMsg.setFooter(botName || "");
|
||||||
if (helpMsg != null) {
|
if (helpMsg != null) {
|
||||||
if (p("command_name")) {
|
if (p("command_name")) {
|
||||||
const cmd: ChatCommand | null = cmdManager.get(p("command_name")?.toString() || "", "CHAT");
|
const cmd: ChatCommand | null = cmdManager.get(p("command_name")?.toString() || "");
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
if (Array.isArray(cmd.guilds) && cmd.guilds.length > 0 && !cmd.guilds.find((g) => i?.guild?.id === g)) {
|
if (Array.isArray(cmd.guilds) && cmd.guilds.length > 0 && !cmd.guilds.find((g) => i?.guild?.id === g)) {
|
||||||
throw new ReferenceError(`Command "${cmd.name}" is not available`);
|
throw new ReferenceError(`Command "${cmd.name}" is not available`);
|
||||||
@@ -64,7 +64,7 @@ export class HelpMessage extends ChatCommand {
|
|||||||
helpMsg.setTitle(params.title);
|
helpMsg.setTitle(params.title);
|
||||||
helpMsg.setDescription(params.bottomText);
|
helpMsg.setDescription(params.bottomText);
|
||||||
|
|
||||||
cmdManager.getList("CHAT").map((c) => {
|
cmdManager.list.map((c) => {
|
||||||
if (
|
if (
|
||||||
c instanceof ChatCommand &&
|
c instanceof ChatCommand &&
|
||||||
c.visible &&
|
c.visible &&
|
||||||
|
|||||||
Reference in new issue
Block a user