adhere to text command setting + some fixes

This commit is contained in:
Erik 2022-07-27 15:32:50 +03:00
parent 669632e6b1
commit f94f512a3d
Signed by untrusted user: Navy.gif
GPG Key ID: 811EC0CD80E7E5FB
6 changed files with 81 additions and 26 deletions

View File

@ -71,6 +71,9 @@ It seems like the mute role was deleted, use the command `-set mute` for more in
[COMMAND_MUTE_MISSING_MODERATE_PERM]
Missing permissions to timeout users (Moderate Member)
[COMMAND_MUTE_HIERARCHY_ERROR]
the bot cannot timeout a user above its highest role
[COMMAND_MUTE_MISSING_MANAGEROLE_PERM]
Missing permissions to manage roles.
@ -303,6 +306,10 @@ the provided role(s) are higher than the bot, I cannot add them
the provided role(s) are not on the grantable list
//History Command
[COMMAND_HISTORY_HELP]
Display moderation history in the server.
Narrow the search down by using the parameters below.
[COMMAND_HISTORY_HISTORY]
Display moderation history for the server or for certain users.

View File

@ -1,3 +1,10 @@
[COMMAND_PING_HELP]
Check if the bot is online.
[COMMAND_AVATAR_HELP]
Display a user's avatar.
Use the member option to display their server avatar.
[COMMAND_AVATAR_FORMATERROR]
Unable to find an avatar with those arguments, try a different size or format.
@ -37,6 +44,8 @@ You have no active reminders.
The content in your reminder was filtered.
// Poll command
[COMMAND_POLL_HELP]
Have the bot send a poll message in a channel with an optional duration.
[COMMAND_POLL_QUESTIONS]
Please respond with question {number}.

View File

@ -91,8 +91,8 @@ class DiscordClient extends Client {
// this.logger.error(`Uncaught exception:\n${err.stack || err}`);
// });
process.on('unhandledRejection', (err, reason) => {
this.logger.error(`Unhandled rejection:\n${err?.stack || err}\n${inspect(reason)}`);
process.on('unhandledRejection', (err) => {
this.logger.error(`Unhandled rejection:\n${err?.stack || err}`);
});
process.on('message', this._handleMessage.bind(this));
@ -309,6 +309,14 @@ class DiscordClient extends Client {
}
format(index, params = {}, opts = {}) {
const {
code = false,
language = 'en_gb'
} = opts;
return this.localeLoader.format(language, index, params, code);
}
getGuildWrapper(id) {
if (this.guildWrappers.has(id)) return this.guildWrappers.get(id);

View File

@ -360,7 +360,7 @@ class GuildWrapper {
}
get prefix() {
return this._settings.prefix || this.client.prefix;
return this._settings.textcommands.prefix || this.client.prefix;
}
get available() {

View File

@ -2,7 +2,9 @@ const { EmbedBuilder, Message, ChannelType, ComponentType, ButtonStyle } = requi
const { Util } = require('../../../utilities');
const { InvokerWrapper, MessageWrapper } = require('../../client/wrappers');
const { Observer, CommandError } = require('../../interfaces/');
const { inspect } = require('util');
// const { inspect } = require('util');
const flagReg = /(?:^| )(?<flag>(?:--[a-z0-9]{3,})|(?:-[a-z]{1,2}))(?:$| )/iu;
class CommandHandler extends Observer {
@ -30,8 +32,10 @@ class CommandHandler extends Observer {
|| message.author.bot
|| message.guild && !message.guild.available) return undefined;
const userWrapper = await this.client.getUserWrapper(message.author.id);
if (!userWrapper.developer) return;
const settings = await message.guildWrapper.settings();
if (!settings.textcommands.enabled && !userWrapper.developer) return;
if(message.guild) {
if(!message.member) await message.guild.members.fetch(message.author.id);
@ -114,6 +118,7 @@ class CommandHandler extends Observer {
const { command } = invoker;
if (response.error && response.index) {
if(!response.emoji) response.emoji = 'failure';
return invoker.reply(response);
} else if (response.error) {
let content = invoker.format(`O_COMMANDHANDLER_TYPE${response.option.type}`, {
@ -288,8 +293,10 @@ class CommandHandler extends Observer {
// Parse flags
for (let index = 0; index < params.length;) {
const match = (/(?:^| )(?<flag>(?:--[a-z0-9]{3,})|(?:-[a-z]{1,2}))(?:$| )/iu).exec(params[index]);
// console.log(params[index]);
const match = flagReg.exec(params[index]);
if (!match) {
// console.log('no match', currentFlag?.name);
if (currentFlag) { // Add potential value resolveables to the flag's raw value until next flag is hit, if there is one
if (currentFlag.plural) { // The parse function only parses consecutive values
if (!currentFlag._rawValue) currentFlag._rawValue = [];
@ -303,13 +310,26 @@ class CommandHandler extends Observer {
continue;
}
const _flag = match.groups.flag.replace(/--?/u, '');
const flag = flags.find((f) => f.name === _flag.toLowerCase());
// console.log('matched');
const _flag = match.groups.flag.replace(/--?/u, '').toLowerCase();
let aliased = false;
const flag = flags.find((f) => {
aliased = f.valueAsAlias && f.choices.some((c) => c.value === _flag);
return f.name === _flag || aliased;
});
if (!flag) return { error: true, index: 'O_COMMANDHANDLER_UNRECOGNISED_FLAG', params: { flag: _flag } };
// console.log('aliased', aliased);
params.splice(index, 1, null);
currentFlag = flag.clone(null, guild);
args[flag.name] = currentFlag;
if (aliased) {
(args[flag.name] = flag.clone(_flag, guild))._aliased = true;
currentFlag = null;
} else {
currentFlag = flag.clone(null, guild);
args[flag.name] = currentFlag;
}
index++;
// console.log('------------------------------');
}
@ -317,13 +337,19 @@ class CommandHandler extends Observer {
for (const flag of Object.values(args)) {
// console.log('flags loop', flag.name, flag._rawValue);
const removed = await flag.parse();
if (removed.error) return { option: flag, ...removed };
if (removed.error) {
if (flag.choices.length) {
return { error: true, index: 'O_COMMANDHANDLER_INVALID_CHOICE', params: { option: flag.name, value: flag._rawValue, choices: flag.choices.map((c) => c.value).join('`, `') } };
}
return { option: flag, ...removed };
}
for(const r of removed) params.splice(params.indexOf(r), 1);
}
// console.log('params', params);
const options = activeCommand.options.filter((opt) => !opt.flag && opt.type !== 'STRING');
const stringOpts = activeCommand.options.filter((opt) => !opt.flag && opt.type === 'STRING');
const options = activeCommand.options.filter((opt) => !opt.flag && (opt.type !== 'STRING' || opt.choices.length));
// const choiceOpts = activeCommand.options.filter((opt) => opt.choices.length);
const stringOpts = activeCommand.options.filter((opt) => !opt.flag && !opt.choices.length && opt.type === 'STRING');
// console.log('non-flag options', options.map((opt) => opt.name));
// Parse out non-flag options
for (const option of options) { // String options are parsed separately at the end
@ -358,39 +384,44 @@ class CommandHandler extends Observer {
const strings = [];
let tmpString = '';
// console.log('strings loop');
// console.log(params);
// Compile strings into groups of strings so we don't get odd looking strings from which options have been parsed out of
for (const str of params) {
for (let index = 0; index < params.length;) {
const str = params[index];
// console.log(str);
if (!str) {
// console.log('null string');
if (tmpString.length) {
// console.log('pushing');
// console.log('pushing', tmpString);
strings.push(tmpString);
tmpString = '';
}
index++;
continue;
}
// params.splice(params.indexOf(str), 1);
params.splice(index, 1);
tmpString += ` ${str}`;
tmpString = tmpString.trim();
}
// console.log('tmpString', tmpString);
if(tmpString.length) strings.push(tmpString);
// console.log('params after', params);
// console.log('strings', strings);
if(strings.length) for (const strOpt of stringOpts) {
if (strings.length) for (const strOpt of stringOpts) {
const cloned = strOpt.clone(strings.shift());
// console.log(cloned.name, cloned._rawValue);
await cloned.parse();
args[cloned.name] = cloned;
}
// This part is obsolete now, I think, the string option checks the choice value
for (const arg of Object.values(args)) {
// console.log(arg.name, arg.value);
if (!arg.choices.length) continue;
if (!arg.choices.some((choice) => {
if (typeof arg.value === 'string') return arg.value.toLowerCase() === choice.value;
if (typeof arg.value === 'string') return arg.value.toLowerCase() === choice.value.toLowerCase();
return arg.value === choice.value;
})) return { error: true, index: 'O_COMMANDHANDLER_INVALID_CHOICE', params: { option: arg.name, value: arg.value, choices: arg.choices.map((c) => c.value).join('`, `') } };
}

View File

@ -215,7 +215,7 @@ class CommandOption {
if (role) {
roles.push(role);
removed.push(str);
} else break;
} else if(roles.length) break;
}
if (!roles.length) return { error: true };
return { value: roles, removed };
@ -228,7 +228,7 @@ class CommandOption {
if (member) {
members.push(member);
removed.push(arg);
} else break;
} else if(members.length) break;
}
if (!members.length) return { error: true, message: this.strict ? this.format('O_COMMANDHANDLER_TYPEMEMBER_STRICT') : null };
return { value: members, removed };
@ -241,7 +241,7 @@ class CommandOption {
if (user) {
users.push(user);
removed.push(arg);
} else break;
} else if(users.length) break;
}
if (!users.length) return { error: true, message: this.strict ? this.format('O_COMMANDHANDLER_TYPEUSERS_STRICT') : null };
return { value: users, removed };
@ -254,7 +254,7 @@ class CommandOption {
if (channel) {
channels.push(channel);
removed.push(arg);
} else break;
} else if(channels.length) break;
}
if (!channels.length) return { error: true };
return { value: channels, removed };
@ -267,7 +267,7 @@ class CommandOption {
if (channel) {
channels.push(channel);
removed.push(arg);
} else break;
} else if(channels.length) break;
}
if (!channels.length) return { error: true };
return { value: channels, removed };
@ -280,7 +280,7 @@ class CommandOption {
if (channel) {
channels.push(channel);
removed.push(arg);
} else break;
} else if(channels.length) break;
}
if (!channels.length) return { error: true };
return { value: channels, removed };
@ -304,7 +304,7 @@ class CommandOption {
if (component && !components.includes(component)) {
components.push(component);
removed.push(str);
} else break;
} else if(components.length) break;
}
if (!components.length) return { error: true };
return { value: components, removed };
@ -323,7 +323,7 @@ class CommandOption {
if (command && !commands.includes(command)) {
commands.push(command);
removed.push(str);
} else break;
} else if(commands.length) break;
}
if (!commands.length) return { error: true };
return { value: commands, removed };