imported localeloader, added some option parsing to command handler. still nowhere near completion.
This commit is contained in:
parent
1224ac96dd
commit
569a00999a
@ -4,7 +4,11 @@
|
|||||||
"developer": "132620781791346688",
|
"developer": "132620781791346688",
|
||||||
"clientId": "697791541690892369",
|
"clientId": "697791541690892369",
|
||||||
"clientOptions": {
|
"clientOptions": {
|
||||||
|
"intents": [
|
||||||
|
"GUILD",
|
||||||
|
"GUILD_MEMBERS",
|
||||||
|
"GUILD_MESSAGES"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"shardOptions": {
|
"shardOptions": {
|
||||||
"totalShards": "auto"
|
"totalShards": "auto"
|
||||||
|
2
src/localization/en_us/commands/en_us_moderation.lang
Normal file
2
src/localization/en_us/commands/en_us_moderation.lang
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
//Mute Command
|
||||||
|
[C_MUTE_DESCRIPTION]
|
@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"developer:test": {
|
|
||||||
"description": "A test command used for testing purposes.",
|
|
||||||
"responses": {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,3 @@
|
|||||||
|
[O_COMMANDHANDLER_COMMANDNOTSYNCED]
|
||||||
|
It appears as if the command does not exist on the client.
|
||||||
|
This is an issue that should be reported to a bot developer.
|
@ -16,17 +16,17 @@ class SlashCommandManager {
|
|||||||
if(message.type === 'global') {
|
if(message.type === 'global') {
|
||||||
await this.global(message.commands);
|
await this.global(message.commands);
|
||||||
} else if(message.type === 'guild') {
|
} else if(message.type === 'guild') {
|
||||||
await this.guild(message.commands, { guilds: message.guilds });
|
await this.guild(message.commands, { guilds: message.guilds, clientId: message.clientId });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async guild(commands, { guilds = [] }) {
|
async guild(commands, { guilds = [], clientId }) {
|
||||||
if(guilds.length === 0) guilds = this.client._options.discord.slashCommands.developerGuilds;
|
if(guilds.length === 0) guilds = this.client._options.discord.slashCommands.developerGuilds;
|
||||||
|
|
||||||
const promises = [];
|
const promises = [];
|
||||||
for(const guild of guilds) {
|
for(const guild of guilds) {
|
||||||
promises.push(this.rest.put(
|
promises.push(this.rest.put(
|
||||||
Routes.applicationGuildCommands(this.client._options.discord.clientId, guild),
|
Routes.applicationGuildCommands(clientId, guild),
|
||||||
{ body: commands }
|
{ body: commands }
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
const { Client, Intents } = require('discord.js');
|
const { Client, Intents } = require('discord.js');
|
||||||
|
|
||||||
const { Logger, Intercom, EventHooker, Registry, Dispatcher, Resolver } = require('./client/');
|
const { Logger, Intercom, EventHooker, LocaleLoader, Registry, Dispatcher, Resolver } = require('./client/');
|
||||||
const { Observer, Command } = require('./interfaces/');
|
const { Observer, Command } = require('./interfaces/');
|
||||||
|
|
||||||
const options = require('../../options.json');
|
const options = require('../../options.json');
|
||||||
@ -11,13 +11,13 @@ class DiscordClient extends Client {
|
|||||||
if(!options) return null;
|
if(!options) return null;
|
||||||
|
|
||||||
super({
|
super({
|
||||||
...options.discord.clientOptions,
|
...options.discord.clientOptions
|
||||||
intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES]
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.eventHooker = new EventHooker(this);
|
this.eventHooker = new EventHooker(this);
|
||||||
this.intercom = new Intercom(this);
|
this.intercom = new Intercom(this);
|
||||||
this.logger = new Logger(this);
|
this.logger = new Logger(this);
|
||||||
|
this.localeLoader = new LocaleLoader(this);
|
||||||
|
|
||||||
this.registry = new Registry(this);
|
this.registry = new Registry(this);
|
||||||
this.dispatcher = new Dispatcher(this);
|
this.dispatcher = new Dispatcher(this);
|
||||||
@ -36,6 +36,9 @@ class DiscordClient extends Client {
|
|||||||
const beforeTime = Date.now();
|
const beforeTime = Date.now();
|
||||||
|
|
||||||
//Initialize components, localization, and observers.
|
//Initialize components, localization, and observers.
|
||||||
|
|
||||||
|
await this.localeLoader.loadLanguages();
|
||||||
|
|
||||||
await this.registry.loadComponents('components/observers', Observer);
|
await this.registry.loadComponents('components/observers', Observer);
|
||||||
await this.registry.loadComponents('components/commands', Command);
|
await this.registry.loadComponents('components/commands', Command);
|
||||||
|
|
||||||
|
@ -24,9 +24,9 @@ class Intercom {
|
|||||||
|
|
||||||
const commands = this.client.registry.components
|
const commands = this.client.registry.components
|
||||||
.filter((c) => c._type === 'command' && c.slash)
|
.filter((c) => c._type === 'command' && c.slash)
|
||||||
.map((c) => c.json);
|
.map((c) => c.shape);
|
||||||
|
|
||||||
this.send('commands', { type: 'guild', commands });
|
this.send('commands', { type: 'guild', commands, clientId: this.client.application.id });
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
82
src/structure/client/LocaleLoader.js
Normal file
82
src/structure/client/LocaleLoader.js
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
const chalk = require('chalk');
|
||||||
|
|
||||||
|
const Util = require('../../Util.js');
|
||||||
|
|
||||||
|
class LocaleLoader {
|
||||||
|
|
||||||
|
constructor(client) {
|
||||||
|
|
||||||
|
this.client = client;
|
||||||
|
|
||||||
|
this.languages = {};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async loadLanguages() {
|
||||||
|
|
||||||
|
const root = path.join(process.cwd(), "src/localization");
|
||||||
|
const directories = fs.readdirSync(root); //locale directories (en_us, fi_fi)
|
||||||
|
|
||||||
|
for(const directory of directories) this._loadLanguage(root, directory);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_loadLanguage(root, language) {
|
||||||
|
|
||||||
|
const directory = path.join(root, language);
|
||||||
|
const files = Util.readdirRecursive(directory);
|
||||||
|
|
||||||
|
const combined = {};
|
||||||
|
for(let file of files) {
|
||||||
|
file = fs.readFileSync(file, {
|
||||||
|
encoding: 'utf8'
|
||||||
|
});
|
||||||
|
const result = this._loadFile(file);
|
||||||
|
Object.assign(combined, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.languages[language] = combined;
|
||||||
|
this.client.logger.info(`Language ${chalk.bold(language)} was ${chalk.bold("loaded")}.`);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_loadFile(file) {
|
||||||
|
|
||||||
|
if(process.platform === 'win32') {
|
||||||
|
file = file.split('\n').join('');
|
||||||
|
file = file.replace(/\r/gu, '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
const lines = file.split('\n');
|
||||||
|
const parsed = {};
|
||||||
|
|
||||||
|
let matched = null,
|
||||||
|
text = [];
|
||||||
|
for(const line of lines) {
|
||||||
|
if(line.startsWith('//') || line.startsWith('#')) continue;
|
||||||
|
const matches = line.match(/\[([_A-Z0-9]{1,})\]/u);
|
||||||
|
if(matches) {
|
||||||
|
if (matched) {
|
||||||
|
parsed[matched] = text.join('\n').trim();
|
||||||
|
[, matched] = matches;
|
||||||
|
text = [];
|
||||||
|
} else {
|
||||||
|
[, matched] = matches;
|
||||||
|
}
|
||||||
|
} else if (matched) {
|
||||||
|
text.push(line);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parsed[matched] = text.join('\n').trim();
|
||||||
|
return parsed;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = LocaleLoader;
|
@ -4,5 +4,6 @@ module.exports = {
|
|||||||
Logger: require('./Logger.js'),
|
Logger: require('./Logger.js'),
|
||||||
Dispatcher: require('./Dispatcher.js'),
|
Dispatcher: require('./Dispatcher.js'),
|
||||||
Registry: require('./Registry.js'),
|
Registry: require('./Registry.js'),
|
||||||
Resolver: require('./Resolver.js')
|
Resolver: require('./Resolver.js'),
|
||||||
|
LocaleLoader: require('./LocaleLoader.js')
|
||||||
};
|
};
|
@ -1,4 +1,4 @@
|
|||||||
const { SlashCommand } = require('../../../interfaces/');
|
const { SlashCommand, CommandOption } = require('../../../interfaces/');
|
||||||
|
|
||||||
class MuteCommand extends SlashCommand {
|
class MuteCommand extends SlashCommand {
|
||||||
|
|
||||||
@ -7,12 +7,36 @@ class MuteCommand extends SlashCommand {
|
|||||||
name: 'mute',
|
name: 'mute',
|
||||||
description: "Silence people.",
|
description: "Silence people.",
|
||||||
module: 'moderation',
|
module: 'moderation',
|
||||||
arguments: [
|
options: [
|
||||||
]
|
new CommandOption({
|
||||||
|
name: 'targets',
|
||||||
|
description: "Provide users to mute.",
|
||||||
|
type: 'MEMBER'
|
||||||
|
}),
|
||||||
|
new CommandOption({
|
||||||
|
name: 'reason',
|
||||||
|
description: "Provide a reason.",
|
||||||
|
type: 'STRING'
|
||||||
|
}),
|
||||||
|
new CommandOption({
|
||||||
|
name: 'points',
|
||||||
|
description: "Assign points to the infraction.",
|
||||||
|
type: 'INTEGER',
|
||||||
|
minimum: 0, maximum: 100
|
||||||
|
}),
|
||||||
|
new CommandOption({
|
||||||
|
name: 'channel',
|
||||||
|
type: 'TEXT_CHANNEL'
|
||||||
|
})
|
||||||
|
],
|
||||||
|
guildOnly: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(thing) {
|
async execute(interaction) {
|
||||||
|
|
||||||
|
// console.log(interaction, interaction.options);
|
||||||
|
interaction.reply(this.resolveable);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const { Observer } = require('../../interfaces/');
|
const { Observer, Thing, CommandOption } = require('../../interfaces/');
|
||||||
|
|
||||||
class CommandHandler extends Observer {
|
class CommandHandler extends Observer {
|
||||||
|
|
||||||
@ -21,8 +21,6 @@ class CommandHandler extends Observer {
|
|||||||
|
|
||||||
async messageCreate(message) {
|
async messageCreate(message) {
|
||||||
|
|
||||||
const { prefix } = this.client._options.discord;
|
|
||||||
|
|
||||||
if(!this.client._built
|
if(!this.client._built
|
||||||
|| message.webhookId
|
|| message.webhookId
|
||||||
|| message.author.bot
|
|| message.author.bot
|
||||||
@ -40,17 +38,122 @@ class CommandHandler extends Observer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async interactionCreate(interaction) {
|
async interactionCreate(interaction) {
|
||||||
if(!interaction.isCommand()) return undefined;
|
if(!interaction.isCommand()
|
||||||
|
&& !interaction.isContextMenu()) return undefined;
|
||||||
|
|
||||||
// if(!this.client._built
|
if(!this.client._built
|
||||||
// || message.guild && !message.guild.available) return undefined;
|
|| !interaction?.guild?.available) return undefined;
|
||||||
|
|
||||||
const command = this._matchCommand(interaction.commandName);
|
const command = this._matchCommand(interaction.commandName);
|
||||||
console.log(interaction.commandName)
|
const thing = new Thing(this.client, command, interaction);
|
||||||
if(!command) return interaction.reply('Command is not synced with client instance.');
|
|
||||||
|
|
||||||
interaction.reply(command.resolveable);
|
if(!command) return thing.reply({ locale: 'O_COMMANDHANDLER_COMMANDNOTSYNCED', emoji: 'failure', ephemeral: true });
|
||||||
|
|
||||||
|
const response = await this._parseInteraction(thing);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async _parseInteraction(thing) {
|
||||||
|
|
||||||
|
const { command, interaction } = thing;
|
||||||
|
|
||||||
|
if(!interaction.guild && command.guildOnly) {
|
||||||
|
return thing.reply({ locale: 'O_COMMANDHANDLER_GUILDONLY', emoji: 'failure', ephemeral: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = [];
|
||||||
|
for(const option of interaction.options._hoistedOptions) {
|
||||||
|
const matched = command.options.find((o) => o.name === option.name);
|
||||||
|
const newOption = new CommandOption({ name: matched.name, type: matched.type, _rawValue: option.value });
|
||||||
|
|
||||||
|
const parsed = await this._parseOption(thing, newOption);
|
||||||
|
if(parsed.error) {
|
||||||
|
//uhh
|
||||||
|
}
|
||||||
|
|
||||||
|
newOption.value = parsed.value;
|
||||||
|
|
||||||
|
options.push(newOption);
|
||||||
|
}
|
||||||
|
console.log(options);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async _parseOption(thing, option) {
|
||||||
|
|
||||||
|
const types = {
|
||||||
|
ROLES: (string) => {
|
||||||
|
|
||||||
|
},
|
||||||
|
MEMBERS: (string) => {
|
||||||
|
|
||||||
|
},
|
||||||
|
USERS: (string) => {
|
||||||
|
|
||||||
|
},
|
||||||
|
CHANNELS: (string) => {
|
||||||
|
|
||||||
|
},
|
||||||
|
TEXT_CHANNELS: (string) => {
|
||||||
|
|
||||||
|
},
|
||||||
|
VOICE_CHANNELS: (string) => {
|
||||||
|
|
||||||
|
},
|
||||||
|
STRING: (string) => {
|
||||||
|
return { error: false, value: string };
|
||||||
|
},
|
||||||
|
INTEGER: (integer) => {
|
||||||
|
if(option.minimum !== undefined && integer < option.minimum) return { error: true };
|
||||||
|
if(option.maximum !== undefined && integer > option.maximum) return { error: true };
|
||||||
|
return { error: false, value: parseInt(integer) };
|
||||||
|
},
|
||||||
|
BOOLEAN: (boolean) => {
|
||||||
|
return { error: false, value: boolean };
|
||||||
|
},
|
||||||
|
MEMBER: async (user) => {
|
||||||
|
let member = null;
|
||||||
|
try {
|
||||||
|
member = await thing.guild.members.fetch(user);
|
||||||
|
} catch(error) {} //eslint-disable-line no-empty
|
||||||
|
if(!member) return { error: true };
|
||||||
|
return { error: false, value: member };
|
||||||
|
},
|
||||||
|
USER: (user) => {
|
||||||
|
return { error: false, value: user };
|
||||||
|
},
|
||||||
|
TEXT_CHANNEL: (channel) => {
|
||||||
|
if(channel.type !== 'GUILD_TEXT') return { error: true };
|
||||||
|
return { error: false, value: channel };
|
||||||
|
},
|
||||||
|
VOICE_CHANNEL: (channel) => {
|
||||||
|
if(channel.type !== 'GUILD_VOICE') return { error: true };
|
||||||
|
return { error: false, value: channel };
|
||||||
|
},
|
||||||
|
CHANNEL: (channel) => {
|
||||||
|
return { error: false, value: channel };
|
||||||
|
},
|
||||||
|
ROLE: (role) => {
|
||||||
|
return { error: false, value: role };
|
||||||
|
},
|
||||||
|
MENTIONABLE: (mentionable) => {
|
||||||
|
return { error: false, value: mentionable };
|
||||||
|
},
|
||||||
|
NUMBER: (number) => {
|
||||||
|
if(option.minimum !== undefined && number < option.minimum) return { error: true };
|
||||||
|
if(option.maximum !== undefined && number > option.maximum) return { error: true };
|
||||||
|
return { error: false, value: number };
|
||||||
|
},
|
||||||
|
FLOAT: (float) => {
|
||||||
|
if(option.minimum !== undefined && float < option.minimum) return { error: true };
|
||||||
|
if(option.maximum !== undefined && float > option.maximum) return { error: true };
|
||||||
|
return { error: false, value: parseFloat(float) };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = types[option.type](option._rawValue);
|
||||||
|
if(result instanceof Promise) await result;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _getCommand(message) {
|
async _getCommand(message) {
|
||||||
@ -58,17 +161,9 @@ class CommandHandler extends Observer {
|
|||||||
//TODO: Move this somewhere else. RegExp should not be created every method call, but it requires the client user to be loaded.
|
//TODO: Move this somewhere else. RegExp should not be created every method call, but it requires the client user to be loaded.
|
||||||
const mentionPattern = new RegExp(`^(<@!?${this.client.user.id}>)`, 'iu');
|
const mentionPattern = new RegExp(`^(<@!?${this.client.user.id}>)`, 'iu');
|
||||||
|
|
||||||
const { prefix } = this.client._options.discord;
|
|
||||||
const start = message.content.slice(0, prefix.length);
|
|
||||||
|
|
||||||
let command = null,
|
let command = null,
|
||||||
parameters = [];
|
parameters = [];
|
||||||
if(start === prefix) {
|
if(mentionPattern.test(message.content)) {
|
||||||
const remaining = message.content.slice(prefix.length);
|
|
||||||
const [ commandName, ...rest ] = remaining.split(" ");
|
|
||||||
command = this._matchCommand(message, commandName);
|
|
||||||
parameters = rest.join(" ");
|
|
||||||
} else if (mentionPattern.test(message.content)) {
|
|
||||||
const [ , commandName, ...rest] = message.content.split(" ");
|
const [ , commandName, ...rest] = message.content.split(" ");
|
||||||
command = this._matchCommand(message, commandName);
|
command = this._matchCommand(message, commandName);
|
||||||
parameters = rest.join(" ");
|
parameters = rest.join(" ");
|
||||||
@ -79,11 +174,11 @@ class CommandHandler extends Observer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_matchCommand(commandName) {
|
_matchCommand(commandName) {
|
||||||
|
|
||||||
const [ command ] = this.client.resolver.components(commandName, 'command', true);
|
const [ command ] = this.client.resolver.components(commandName, 'command', true);
|
||||||
if(!command) return null;
|
return command || null;
|
||||||
|
}
|
||||||
|
|
||||||
return command;
|
_generateError() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
60
src/structure/interfaces/CommandOption.js
Normal file
60
src/structure/interfaces/CommandOption.js
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
const Constants = {
|
||||||
|
CommandOptionTypes: {
|
||||||
|
SUB_COMMAND: 1,
|
||||||
|
SUB_COMMAND_GROUP: 2,
|
||||||
|
ROLES: 3, //Note plurality, strings can parse users, roles, and channels.
|
||||||
|
MEMBERS: 3,
|
||||||
|
USERS: 3,
|
||||||
|
CHANNELS: 3,
|
||||||
|
TEXT_CHANNELS: 3,
|
||||||
|
VOICE_CHANNELS: 3,
|
||||||
|
STRING: 3,
|
||||||
|
INTEGER: 4,
|
||||||
|
BOOLEAN: 5,
|
||||||
|
MEMBER: 6,
|
||||||
|
USER: 6,
|
||||||
|
TEXT_CHANNEL: 7,
|
||||||
|
VOICE_CHANNEL: 7,
|
||||||
|
CHANNEL: 7,
|
||||||
|
ROLE: 8,
|
||||||
|
MENTIONABLE: 9,
|
||||||
|
NUMBER: 10,
|
||||||
|
FLOAT: 10
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CommandOption {
|
||||||
|
|
||||||
|
constructor(options = {}) {
|
||||||
|
|
||||||
|
this.name = options.name;
|
||||||
|
this.description = options.description || "A missing description, let a bot developer know.";
|
||||||
|
|
||||||
|
this.type = Object.keys(Constants.CommandOptionTypes).includes(options.type) ? options.type : 'STRING';
|
||||||
|
this.required = Boolean(options.required);
|
||||||
|
this.choices = options.choices || []; //Used for STRING/INTEGER/NUMBER types.
|
||||||
|
this.options = options.options || []; //Used for SUB_COMMAND/SUB_COMMAND_GROUP types.
|
||||||
|
|
||||||
|
this.minimum = options.minimum || undefined; //Used for INTEGER/NUMBER/FLOAT types.
|
||||||
|
this.maxiumum = options.maximum || undefined;
|
||||||
|
|
||||||
|
this.value = undefined;
|
||||||
|
|
||||||
|
this._rawValue = options._rawValue || null; //Raw value input from Discord.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
get shape() {
|
||||||
|
return {
|
||||||
|
name: this.name,
|
||||||
|
description: this.description,
|
||||||
|
type: Constants.CommandOptionTypes[this.type],
|
||||||
|
required: this.required,
|
||||||
|
choices: this.choices,
|
||||||
|
options: this.options.map((o) => o.shape)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = CommandOption;
|
@ -1,71 +1,74 @@
|
|||||||
const { Emojis } = require('../../constants');
|
const { Emojis } = require('../../constants/');
|
||||||
|
|
||||||
class Thing {
|
class Thing {
|
||||||
|
|
||||||
constructor(client, options = {}) {
|
constructor(client, command, interaction) {
|
||||||
if(!options) return null;
|
|
||||||
|
|
||||||
this.message = options.message || null;
|
this.client = client;
|
||||||
this.interaction = options.interaction || null;
|
this.interaction = interaction;
|
||||||
|
this.command = command;
|
||||||
|
|
||||||
this.command = options.command; //Should always be provided.
|
this.options = [];
|
||||||
this.arguments = options.arguments;
|
|
||||||
|
|
||||||
this.parameters = options.parameters || [];
|
this._guild = null;
|
||||||
|
this._channel = null;
|
||||||
|
|
||||||
this._resolved = false;
|
this._pending = null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async resolve() {
|
async reply(options = {}) {
|
||||||
|
|
||||||
if(this.command.showUsage && !this.parameters.length && !this.arguments.length) {
|
if(options.locale) {
|
||||||
console.log('Show usage embed'); //eslint-disable-line no-console
|
options.content = this.format(options.locale);
|
||||||
return undefined;
|
// delete options.locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
if(options.emoji) {
|
||||||
const response = this.command.execute(this);
|
if(!Emojis[options.emoji]) this.client.logger.warn(`Invalid emoji provided to command ${this.command.resolveable}: "${options.emoji}"`);
|
||||||
if(response instanceof Promise) await response;
|
options.content = `${Emojis[options.emoji]}${options.content}`;
|
||||||
this.command._invokes.successes++;
|
// delete options.emoji;
|
||||||
this.client.emit('commandExecute', { instance: this, type: 'SUCCESS' });
|
|
||||||
return { error: false };
|
|
||||||
} catch(error) {
|
|
||||||
this.command._invokes.failures++;
|
|
||||||
this.client.emit('commandExecute', { instance: this, type: 'FAILURE' });
|
|
||||||
return { error: true, message: error };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._pending = this.interaction.reply(options);
|
||||||
|
return this._pending;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
format(locale) {
|
||||||
async respond(content, options = {}) {
|
const language = 'en_us'; //Default language.
|
||||||
if(typeof content === 'string') {
|
//TODO: Fetch guild/user settings and switch localization.
|
||||||
if(options.emoji && Emojis[options.emoji]) {
|
return this.client.localeLoader.languages[language][locale];
|
||||||
content = `${Emojis[options.emoji]} ${content}`;
|
|
||||||
}
|
|
||||||
if(options.reply) content = `<@${this.message.author.id}> ${content}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get guild() {
|
||||||
|
return this.interaction.guild || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async send(options) {
|
get channel() {
|
||||||
if(this.type === 'MESSAGE') {
|
return this.interaction.channel || null;
|
||||||
this.message.channel.send({
|
|
||||||
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.interaction.reply({
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get type() {
|
// async guild() {
|
||||||
if(this.message) return 'MESSAGE';
|
// if(!this.interaction.guild) return null;
|
||||||
return 'INTERACTION';
|
// if(this._guild) return this._guild;
|
||||||
|
// this._guild = await this.client.guilds.fetch(this.interaction.guildId);
|
||||||
|
// return this._guild;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// async channel() {
|
||||||
|
// if(!this.interaction.channel) return null;
|
||||||
|
// if(this._channel) return this._channel;
|
||||||
|
// this._channel = await this.client.channels.fetch(this.interaction.channelId);
|
||||||
|
// return this._channel;
|
||||||
|
// }
|
||||||
|
|
||||||
|
get user() {
|
||||||
|
return this.interaction.user || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get member() {
|
||||||
|
return this.interaction.member || null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Thing;
|
module.exports = Thing;
|
@ -1,4 +1,4 @@
|
|||||||
const Component = require('./Component.js');
|
const Component = require('../Component.js');
|
||||||
|
|
||||||
class Command extends Component {
|
class Command extends Component {
|
||||||
|
|
||||||
@ -25,7 +25,8 @@ class Command extends Component {
|
|||||||
this.guildOnly = Boolean(options?.guildOnly);
|
this.guildOnly = Boolean(options?.guildOnly);
|
||||||
|
|
||||||
this.archivable = options.archivable === undefined ? true : Boolean(options.archivable);
|
this.archivable = options.archivable === undefined ? true : Boolean(options.archivable);
|
||||||
this.slash = Boolean(options?.slash);
|
|
||||||
|
this.slash = Boolean(options.slash);
|
||||||
|
|
||||||
this._invokes = {
|
this._invokes = {
|
||||||
success: 0,
|
success: 0,
|
8
src/structure/interfaces/commands/LegacyCommand.js
Normal file
8
src/structure/interfaces/commands/LegacyCommand.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
const { Command } = require('./Command.js');
|
||||||
|
|
||||||
|
class LegacyCommand extends Command {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = LegacyCommand;
|
@ -1,5 +1,5 @@
|
|||||||
const Command = require('./Command.js');
|
const Command = require('./Command.js');
|
||||||
const { Commands: CommandsConstant } = require('../../constants/');
|
const { Commands: CommandsConstant } = require('../../../constants/');
|
||||||
|
|
||||||
class SlashCommand extends Command {
|
class SlashCommand extends Command {
|
||||||
|
|
||||||
@ -21,16 +21,16 @@ class SlashCommand extends Command {
|
|||||||
|
|
||||||
this.type = Object.keys(CommandsConstant.ApplicationCommandTypes).includes(options.type) ? options.type : 'CHAT_INPUT';
|
this.type = Object.keys(CommandsConstant.ApplicationCommandTypes).includes(options.type) ? options.type : 'CHAT_INPUT';
|
||||||
this.options = options.options || [];
|
this.options = options.options || [];
|
||||||
this.defaultPermission = options.defaultPermission || {};
|
this.defaultPermission = options.defaultPermission || true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get json() {
|
get shape() {
|
||||||
return {
|
return {
|
||||||
name: this.name,
|
name: this.name,
|
||||||
description: this.description,
|
description: this.description,
|
||||||
type: CommandsConstant.ApplicationCommandTypes[this.type],
|
type: CommandsConstant.ApplicationCommandTypes[this.type],
|
||||||
options: this.options,
|
options: this.options.map((o) => o.shape),
|
||||||
defaultPermission: this.defaultPermission
|
defaultPermission: this.defaultPermission
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -2,7 +2,8 @@ module.exports = {
|
|||||||
Component: require('./Component.js'),
|
Component: require('./Component.js'),
|
||||||
Observer: require('./Observer.js'),
|
Observer: require('./Observer.js'),
|
||||||
Module: require('./Module.js'),
|
Module: require('./Module.js'),
|
||||||
SlashCommand: require('./SlashCommand.js'),
|
SlashCommand: require('./commands/SlashCommand.js'),
|
||||||
Command: require('./Command.js'),
|
Command: require('./commands/Command.js'),
|
||||||
|
CommandOption: require('./CommandOption.js'),
|
||||||
Thing: require('./Thing.js')
|
Thing: require('./Thing.js')
|
||||||
};
|
};
|
Loading…
Reference in New Issue
Block a user