forked from Galactic/galactic-bot
grant/revoke basework, component command, guild wrapper rework (broke settings)
This commit is contained in:
parent
b9cfd331c5
commit
a630bf37ed
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,3 +4,4 @@ node_modules
|
|||||||
yarn-error.log
|
yarn-error.log
|
||||||
.eslintrc.json
|
.eslintrc.json
|
||||||
logs
|
logs
|
||||||
|
permissionExample.json
|
@ -25,11 +25,11 @@ class LocaleLoader {
|
|||||||
const _directory = path.join(process.cwd(), 'language/languages');
|
const _directory = path.join(process.cwd(), 'language/languages');
|
||||||
const directories = fs.readdirSync(_directory); //locale directories, ex. en_us, fi
|
const directories = fs.readdirSync(_directory); //locale directories, ex. en_us, fi
|
||||||
|
|
||||||
for (const directory of directories) await this.loadLanguage(directory);
|
for (const directory of directories) this.loadLanguage(directory);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadLanguage(language) {
|
loadLanguage(language) {
|
||||||
|
|
||||||
this.client.logger.info(`Loading locale ${chalk.bold(language)}`);
|
this.client.logger.info(`Loading locale ${chalk.bold(language)}`);
|
||||||
const directory = path.join(process.cwd(), `language/languages/${language}`);
|
const directory = path.join(process.cwd(), `language/languages/${language}`);
|
||||||
@ -76,7 +76,7 @@ class LocaleLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(const [ key, value ] of Object.entries(parsed)) {
|
for(const [ key, value ] of Object.entries(parsed)) {
|
||||||
parsed[key] = value.replace(/^(\r)|(\r){1,}$/g, '')
|
parsed[key] = value.replace(/^(\r)|(\r){1,}$/g, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
return parsed;
|
return parsed;
|
||||||
|
20
language/languages/en_us/commands/en_us_administrator.lang
Normal file
20
language/languages/en_us/commands/en_us_administrator.lang
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
//Grant Command
|
||||||
|
|
||||||
|
[C_GRANT_DESCRIPTION]
|
||||||
|
Grant roles or users permissions for commands or modules.
|
||||||
|
|
||||||
|
[C_GRANT_RESOLVEERROR]
|
||||||
|
Unable to find any roles or members, view `{prefix}cmd grant` for more help.
|
||||||
|
|
||||||
|
[C_GRANT_MISSINGPERMPARAM]
|
||||||
|
You must provide permissions to grant, view `{prefix}cmd grant` for more help.
|
||||||
|
|
||||||
|
//Revoke Command
|
||||||
|
|
||||||
|
[C_REVOKE_DESCRIPTION]
|
||||||
|
Revoke permissions granted to roles or users.
|
||||||
|
|
||||||
|
//Permissions Command
|
||||||
|
|
||||||
|
[C_PERMISSIONS_DESCRIPTION]
|
||||||
|
View permissions granted to roles or users.
|
5
language/languages/en_us/commands/en_us_developer.lang
Normal file
5
language/languages/en_us/commands/en_us_developer.lang
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[C_EVALUATE_DESCRIPTION]
|
||||||
|
Evaluates javascript code.
|
||||||
|
|
||||||
|
[C_RELOAD_DESCRIPTION]
|
||||||
|
Reloads components and language files.
|
@ -1,3 +0,0 @@
|
|||||||
[C_HELP_404]
|
|
||||||
**ERROR:**
|
|
||||||
`{component}` was not found!
|
|
@ -1,4 +1,9 @@
|
|||||||
[C_HELP_USAGE]
|
//Help Command
|
||||||
|
|
||||||
|
[C_HELP_DESCRIPTION]
|
||||||
|
Shows helpful information for commands, settings, and moderation.
|
||||||
|
|
||||||
|
[C_HELP]
|
||||||
**__HELP MENU__**
|
**__HELP MENU__**
|
||||||
For a list of all available commands, use `{prefix}commands [ group ]`.
|
For a list of all available commands, use `{prefix}commands [ group ]`.
|
||||||
|
|
||||||
@ -12,6 +17,8 @@ The bot splits arguments by space unless specified otherwise. To pass an argumen
|
|||||||
**❯ Documentation notation**
|
**❯ Documentation notation**
|
||||||
**Optional** arguments are denoted by being encapsulated in brackets `[ ]` - means that the command will run either with default values or show usage prompt.
|
**Optional** arguments are denoted by being encapsulated in brackets `[ ]` - means that the command will run either with default values or show usage prompt.
|
||||||
**Required** arguments are denoted by less and greater than `< >` - means that the command will not run and return an error.
|
**Required** arguments are denoted by less and greater than `< >` - means that the command will not run and return an error.
|
||||||
|
**Infinite** arguments (ones you can list several) are denoted by `..` after the argument. Ex `< argument.. >` - means you can pass more than one argument.
|
||||||
|
**Alternatives** are denoted by being separated by a `|`.
|
||||||
|
|
||||||
**❯ Moderation**
|
**❯ Moderation**
|
||||||
For help with moderation, see `{prefix}help modhelp`.
|
For help with moderation, see `{prefix}help modhelp`.
|
||||||
@ -35,4 +42,23 @@ __**{component} HELP**__
|
|||||||
|
|
||||||
[C_HELP_HELP]
|
[C_HELP_HELP]
|
||||||
Shows information about the bot and component usage.
|
Shows information about the bot and component usage.
|
||||||
To show help for commands `{prefix}help [ command ]`
|
To show help for commands `{prefix}help [command]`
|
||||||
|
|
||||||
|
//Commands Command
|
||||||
|
|
||||||
|
[C_COMMANDS_DESCRIPTION]
|
||||||
|
Displays all commands and help.
|
||||||
|
|
||||||
|
[C_COMMANDS_TITLE]
|
||||||
|
Available commands
|
||||||
|
|
||||||
|
[C_COMMANDS_TEMPLATE]
|
||||||
|
Displaying commands for module `{mod}`.
|
||||||
|
|
||||||
|
{text}
|
||||||
|
|
||||||
|
[C_COMMANDS]
|
||||||
|
__Commands that are struck through are disabled.__
|
||||||
|
|
||||||
|
[C_COMMANDS_FOOTER]
|
||||||
|
To search by specific module, use {prefix}commands [ module ]
|
@ -3,8 +3,14 @@
|
|||||||
[C_PING_RESPONSE]
|
[C_PING_RESPONSE]
|
||||||
Pong!
|
Pong!
|
||||||
|
|
||||||
|
[C_PING_DESCRIPTION]
|
||||||
|
Shows the millisecond delay between the bot and the discord server.
|
||||||
|
|
||||||
//Settings Command
|
//Settings Command
|
||||||
|
|
||||||
|
[C_SETTINGS_DESCRIPTION]
|
||||||
|
Configure your guild and user settings.
|
||||||
|
|
||||||
[C_SETTINGS_ADMINISTRATORERROR]
|
[C_SETTINGS_ADMINISTRATORERROR]
|
||||||
You must have the `ADMINISTRATOR` permission to reset the {type} settings.
|
You must have the `ADMINISTRATOR` permission to reset the {type} settings.
|
||||||
|
|
||||||
@ -43,6 +49,9 @@ That setting does not exist!
|
|||||||
|
|
||||||
//User Command
|
//User Command
|
||||||
|
|
||||||
|
[C_USER_DESCRIPTION]
|
||||||
|
Search for users or view user information.
|
||||||
|
|
||||||
[C_USER]
|
[C_USER]
|
||||||
**Nickname:** {nickname}
|
**Nickname:** {nickname}
|
||||||
**User:** <@{id}>
|
**User:** <@{id}>
|
||||||
|
@ -11,5 +11,11 @@ switch({component}) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
[EXAMPLES]
|
[GENERAL_EXAMPLES]
|
||||||
Example usage
|
Example Usage
|
||||||
|
|
||||||
|
[GENERAL_ALIASES]
|
||||||
|
Aliases
|
||||||
|
|
||||||
|
[GENERAL_ARGUMENTS]
|
||||||
|
Arguments
|
@ -15,3 +15,5 @@ Information
|
|||||||
|
|
||||||
[M_MUSIC_NAME]
|
[M_MUSIC_NAME]
|
||||||
Music
|
Music
|
||||||
|
|
||||||
|
[
|
||||||
|
@ -19,7 +19,7 @@ class DiscordWebhook extends Transport {
|
|||||||
|
|
||||||
log(info, callback) {
|
log(info, callback) {
|
||||||
setImmediate(() => {
|
setImmediate(() => {
|
||||||
this.emit('logged', info);
|
this.emit('logged', info);
|
||||||
});
|
});
|
||||||
|
|
||||||
const message = info.message.replace(regex, '')
|
const message = info.message.replace(regex, '')
|
||||||
|
@ -10,7 +10,7 @@ const Logger = require('./Logger.js');
|
|||||||
const TransactionHandler = require('./TransactionHandler.js');
|
const TransactionHandler = require('./TransactionHandler.js');
|
||||||
const LocaleLoader = require('../../language/LocaleLoader.js');
|
const LocaleLoader = require('../../language/LocaleLoader.js');
|
||||||
|
|
||||||
const { Guild, User, Message } = require('../../structure/extensions/'); //eslint-disable-line
|
const { Guild, GuildMember, User, Message } = require('../../structure/extensions/'); //eslint-disable-line no-unused-vars
|
||||||
const { Command, Observer, Inhibitor, Setting } = require('../../structure/interfaces/');
|
const { Command, Observer, Inhibitor, Setting } = require('../../structure/interfaces/');
|
||||||
|
|
||||||
class DiscordClient extends Client {
|
class DiscordClient extends Client {
|
||||||
@ -47,7 +47,7 @@ class DiscordClient extends Client {
|
|||||||
|
|
||||||
await super.login(this._options.bot.token);
|
await super.login(this._options.bot.token);
|
||||||
|
|
||||||
await this.localeLoader.loadLanguages();
|
this.localeLoader.loadLanguages();
|
||||||
|
|
||||||
await this.registry.loadComponents('components/inhibitors/', Inhibitor);
|
await this.registry.loadComponents('components/inhibitors/', Inhibitor);
|
||||||
await this.registry.loadComponents('components/commands/', Command);
|
await this.registry.loadComponents('components/commands/', Command);
|
||||||
@ -69,7 +69,7 @@ class DiscordClient extends Client {
|
|||||||
def = {
|
def = {
|
||||||
...def,
|
...def,
|
||||||
...setting.default
|
...setting.default
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this._defaultConfig = def;
|
this._defaultConfig = def;
|
||||||
|
@ -24,12 +24,14 @@ class Registry {
|
|||||||
const func = require(path);
|
const func = require(path);
|
||||||
if(typeof func !== 'function') {
|
if(typeof func !== 'function') {
|
||||||
this.client.logger.warn("Attempted to index an invalid function as a component.");
|
this.client.logger.warn("Attempted to index an invalid function as a component.");
|
||||||
|
delete require.cache[path];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const component = new func(this.client); //Instantiates the component class.
|
const component = new func(this.client); //Instantiates the component class.
|
||||||
if(classToHandle && !(component instanceof classToHandle)) {
|
if(classToHandle && !(component instanceof classToHandle)) {
|
||||||
this.client.logger.warn("Attempted to load an invalid class.");
|
this.client.logger.warn("Attempted to load an invalid class.");
|
||||||
|
delete require.cache[path];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,6 +46,7 @@ class Registry {
|
|||||||
async loadComponent(component, directory) {
|
async loadComponent(component, directory) {
|
||||||
|
|
||||||
if(!(component instanceof Component)) {
|
if(!(component instanceof Component)) {
|
||||||
|
delete require.cache[directory];
|
||||||
this.client.logger.warn("Attempted to load an invalid component.");
|
this.client.logger.warn("Attempted to load an invalid component.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -69,7 +72,10 @@ class Registry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async unloadComponent(component) {
|
async unloadComponent(component) {
|
||||||
this.components.delete(component.id);
|
if(component.module) {
|
||||||
|
component.module.components.delete(component.resolveable);
|
||||||
|
}
|
||||||
|
this.components.delete(component.resolveable);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -161,13 +161,13 @@ class Resolver {
|
|||||||
if(/<@!?([0-9]{17,21})>/.test(resolveable)) {
|
if(/<@!?([0-9]{17,21})>/.test(resolveable)) {
|
||||||
|
|
||||||
let id = resolveable.match(/<@!?([0-9]{17,21})>/)[1];
|
let id = resolveable.match(/<@!?([0-9]{17,21})>/)[1];
|
||||||
let member = await members.fetch(id).catch(err => { if(err.code === 10007) return false; else { console.warn(err); return false; } });
|
let member = await members.fetch(id).catch(err => { if(err.code === 10007) return false; else { this.client.logger.warn(err); return false; } });
|
||||||
if(member) resolved.push(member);
|
if(member) resolved.push(member);
|
||||||
|
|
||||||
} else if(/(id\:)?([0-9]{17,21})/.test(resolveable)) {
|
} else if(/(id\:)?([0-9]{17,21})/.test(resolveable)) {
|
||||||
|
|
||||||
let id = resolveable.match(/(id\:)?([0-9]{17,21})/)[2];
|
let id = resolveable.match(/(id\:)?([0-9]{17,21})/)[2];
|
||||||
let member = await members.fetch(id).catch(err => { if(err.code === 10007) return false; else { console.warn(err); return false; } });
|
let member = await members.fetch(id).catch(err => { if(err.code === 10007) return false; else { this.client.logger.warn(err); return false; } });
|
||||||
if(member) resolved.push(member);
|
if(member) resolved.push(member);
|
||||||
|
|
||||||
} else if(/^\@?([\S\s]{1,32})\#([0-9]{4})/.test(resolveable)) {
|
} else if(/^\@?([\S\s]{1,32})\#([0-9]{4})/.test(resolveable)) {
|
||||||
@ -175,21 +175,21 @@ class Resolver {
|
|||||||
let m = resolveable.match(/^\@?([\S\s]{1,32})\#([0-9]{4})/);
|
let m = resolveable.match(/^\@?([\S\s]{1,32})\#([0-9]{4})/);
|
||||||
let username = m[1].toLowerCase();
|
let username = m[1].toLowerCase();
|
||||||
let discrim = m[2].toLowerCase();
|
let discrim = m[2].toLowerCase();
|
||||||
let [ member ] = members.cache.filter(m => {
|
let member = members.cache.filter(m => {
|
||||||
return m.user.username.toLowerCase() === username && m.user.discriminator === discrim;
|
return m.user.username.toLowerCase() === username && m.user.discriminator === discrim;
|
||||||
}).first(1);
|
}).first();
|
||||||
if(member) resolved.push(member);
|
if(member) resolved.push(member);
|
||||||
|
|
||||||
} else if(/^\@?([\S\s]{1,32})/.test(resolveable) && guild && !strict) {
|
} else if(/^\@?([\S\s]{1,32})/.test(resolveable) && guild && !strict) {
|
||||||
|
|
||||||
let nickname = resolveable.match(/^\@?([\S\s]{1,32})/)[0].toLowerCase();
|
let nickname = resolveable.match(/^\@?([\S\s]{1,32})/)[0].toLowerCase();
|
||||||
let [ member ] = members.cache.filter((m) => {
|
let member = members.cache.filter((m) => {
|
||||||
return (m && m.user) &&
|
return (m && m.user) &&
|
||||||
((!m.nickname ? false : m.nickname.toLowerCase() == nickname ) ||
|
((!m.nickname ? false : m.nickname.toLowerCase() == nickname ) ||
|
||||||
(!m.nickname ? false : m.nickname.toLowerCase().includes(nickname)) ||
|
(!m.nickname ? false : m.nickname.toLowerCase().includes(nickname)) ||
|
||||||
m.user.username.toLowerCase().includes(nickname) ||
|
m.user.username.toLowerCase().includes(nickname) ||
|
||||||
m.user.username.toLowerCase() == nickname);
|
m.user.username.toLowerCase() == nickname);
|
||||||
}).first(1);
|
}).first();
|
||||||
if(member) resolved.push(member);
|
if(member) resolved.push(member);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -200,6 +200,13 @@ class Resolver {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async resolveMember(resolveable, guild, strict) {
|
||||||
|
|
||||||
|
let result = await this.resolveMembers([ resolveable ], guild, strict);
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve multiple channels
|
* Resolve multiple channels
|
||||||
*
|
*
|
||||||
@ -227,12 +234,12 @@ class Resolver {
|
|||||||
let name = /^\#?([a-z0-9\-\_0]*)/i;
|
let name = /^\#?([a-z0-9\-\_0]*)/i;
|
||||||
let id = /^\<\#([0-9]*)\>/i;
|
let id = /^\<\#([0-9]*)\>/i;
|
||||||
|
|
||||||
if(name.test(resolveable)) {
|
if (name.test(resolveable)) {
|
||||||
|
|
||||||
let match = resolveable.match(name);
|
let match = resolveable.match(name);
|
||||||
let ch = match[1].toLowerCase();
|
let ch = match[1].toLowerCase();
|
||||||
|
|
||||||
let channel = channels.cache.filter(c => {
|
let [ channel ] = channels.cache.filter(c => {
|
||||||
if(!strict) return c.name.toLowerCase().includes(ch);
|
if(!strict) return c.name.toLowerCase().includes(ch);
|
||||||
return c.name.toLowerCase() === ch;
|
return c.name.toLowerCase() === ch;
|
||||||
}).first(1);
|
}).first(1);
|
||||||
@ -287,7 +294,7 @@ class Resolver {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
let role = roles.cache.filter(r => {
|
let [ role ] = roles.cache.filter(r => {
|
||||||
if(!strict) return r.name.toLowerCase().includes(resolveable.toLowerCase());
|
if(!strict) return r.name.toLowerCase().includes(resolveable.toLowerCase());
|
||||||
return r.name.toLowerCase() === resolveable.toLowerCase();
|
return r.name.toLowerCase() === resolveable.toLowerCase();
|
||||||
}).first(1);
|
}).first(1);
|
||||||
|
101
structure/client/components/commands/administrator/Grant.js
Normal file
101
structure/client/components/commands/administrator/Grant.js
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
const { Command, Argument } = require('../../../../interfaces/');
|
||||||
|
|
||||||
|
class GrantCommand extends Command {
|
||||||
|
|
||||||
|
constructor(client) {
|
||||||
|
|
||||||
|
super(client, {
|
||||||
|
name: 'grant',
|
||||||
|
module: 'administrator',
|
||||||
|
usage: "<role|user> <permissions..>",
|
||||||
|
examples: [
|
||||||
|
"\"Server Moderators\" module:moderation",
|
||||||
|
"@nolan#2887 command:kick"
|
||||||
|
],
|
||||||
|
memberPermissions: ['ADMINISTRATOR'],
|
||||||
|
showUsage: true,
|
||||||
|
guildOnly: true,
|
||||||
|
arguments: [
|
||||||
|
new Argument(client, {
|
||||||
|
name: 'channel',
|
||||||
|
aliases: [
|
||||||
|
'channels'
|
||||||
|
],
|
||||||
|
type: 'CHANNEL',
|
||||||
|
types: ['FLAG', 'VERBAL'],
|
||||||
|
infinite: true
|
||||||
|
})
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async execute(message, { params, args }) {
|
||||||
|
|
||||||
|
const _permissions = await message.guild.permissions_();
|
||||||
|
|
||||||
|
const [ parse, ...perms ] = params;
|
||||||
|
const resolveable = await this._parseResolveable(message, parse);
|
||||||
|
if(perms.length === 0) {
|
||||||
|
await message.respond(message.format('C_GRANT_MISSINGPERMPARAM'), { emoji: 'failure' });
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const permissions = this.client.registry.components.filter(c=>
|
||||||
|
c.type === 'command'
|
||||||
|
|| c.type === 'module'
|
||||||
|
);
|
||||||
|
|
||||||
|
let parsed = [];
|
||||||
|
let failed = [];
|
||||||
|
for(const perm of perms) {
|
||||||
|
const search = permissions.filter(filterInexact(perm)).first();
|
||||||
|
if(!search) failed.push(perm);
|
||||||
|
if(search.type === 'module') {
|
||||||
|
for(const component of search.components.values()) {
|
||||||
|
if(component.type === 'command') parsed.push(component.resolveable);
|
||||||
|
//add check for grantable
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//add check for grantable
|
||||||
|
parsed.push(search.resolveable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = {};
|
||||||
|
let existing = _permissions[resolveable.id];
|
||||||
|
if(existing) {
|
||||||
|
for(let perm of parsed) {
|
||||||
|
if(existing.includes(perm)) failed.push(perm);
|
||||||
|
else existing.push(perm);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
existing = parsed;
|
||||||
|
}
|
||||||
|
data = existing;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async _parseResolveable(message, resolveable) {
|
||||||
|
let parsed = await this.client.resolver.resolveRoles(resolveable, message.guild);
|
||||||
|
if(!parsed) {
|
||||||
|
parsed = await this.client.resolver.resolveMembers(resolveable, message.guild);
|
||||||
|
if(!parsed) {
|
||||||
|
await message.respond(message.format('C_GRANT_RESOLVEERROR'), { emoji: 'failure' });
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parsed[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = GrantCommand;
|
||||||
|
|
||||||
|
const filterInexact = (search) => {
|
||||||
|
return comp => comp.id.toLowerCase().includes(search) ||
|
||||||
|
comp.resolveable.toLowerCase().includes(search) ||
|
||||||
|
(comp.aliases && (comp.aliases.some(ali => `${comp.type}:${ali}`.toLowerCase().includes(search)) ||
|
||||||
|
comp.aliases.some(ali => ali.toLowerCase().includes(search))));
|
||||||
|
};
|
37
structure/client/components/commands/administrator/Revoke.js
Normal file
37
structure/client/components/commands/administrator/Revoke.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
const { Command, Argument } = require('../../../../interfaces/');
|
||||||
|
|
||||||
|
class RevokeCommand extends Command {
|
||||||
|
|
||||||
|
constructor(client) {
|
||||||
|
|
||||||
|
super(client, {
|
||||||
|
name: 'revoke',
|
||||||
|
module: 'administrator',
|
||||||
|
usage: "<role|user> <permissions..>",
|
||||||
|
examples: [
|
||||||
|
"\"Server Moderators\" module:moderation",
|
||||||
|
"@nolan#2887 command:kick"
|
||||||
|
],
|
||||||
|
memberPermissions: ['ADMINISTRATOR'],
|
||||||
|
showUsage: true,
|
||||||
|
guildOnly: true,
|
||||||
|
arguments: [
|
||||||
|
new Argument(client, {
|
||||||
|
name: 'channel',
|
||||||
|
type: 'CHANNEL',
|
||||||
|
types: ['FLAG', 'VERBAL'],
|
||||||
|
})
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async execute(message, { params, args }) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = RevokeCommand;
|
158
structure/client/components/commands/developer/Component.js
Normal file
158
structure/client/components/commands/developer/Component.js
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
const { Command } = require('../../../../interfaces/');
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
class ComponentCommand extends Command {
|
||||||
|
|
||||||
|
constructor(client) {
|
||||||
|
|
||||||
|
super(client, {
|
||||||
|
name: 'component',
|
||||||
|
module: 'developer',
|
||||||
|
restricted: true,
|
||||||
|
aliases: [
|
||||||
|
'c',
|
||||||
|
'comp'
|
||||||
|
],
|
||||||
|
usage: '[component..]',
|
||||||
|
arguments: [
|
||||||
|
// new Argument(client, {
|
||||||
|
// name: 'reload',
|
||||||
|
// type: 'STRING',
|
||||||
|
// types: ['FLAG'],
|
||||||
|
// aliases: [ 'r' ],
|
||||||
|
// description: "Reloads the language library",
|
||||||
|
// default: 'all'
|
||||||
|
// })
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
this.client = client;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async execute(message, { params }) {
|
||||||
|
|
||||||
|
//<load|unload|reload|disable|enable> <component>
|
||||||
|
const method = params.shift().toLowerCase();
|
||||||
|
let response;
|
||||||
|
|
||||||
|
if (method === 'reload')
|
||||||
|
response = this._handleReload(params);
|
||||||
|
else if (method === 'enable')
|
||||||
|
response = this._handleDisableEnable(params.shift().toLowerCase(), true);
|
||||||
|
else if (method === 'disable')
|
||||||
|
response = this._handleDisableEnable(params.shift().toLowerCase(), false);
|
||||||
|
else if (method === 'load')
|
||||||
|
response = this._handleLoadUnload(params.shift().toLowerCase(), true);
|
||||||
|
else if (method === 'unload')
|
||||||
|
response = this._handleLoadUnload(params.shift().toLowerCase(), false);
|
||||||
|
else return await message.respond('Invalid method. Can only be `reload`, `enable`, `disable`, `load`, `unload`', 'failure');
|
||||||
|
|
||||||
|
return await message.respond(response.msg, { emoji: response.error ? 'failure' : 'success' });
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_handleReload(params) {
|
||||||
|
|
||||||
|
const name = params.length ? params.shift().toLowerCase() : 'all'; //ex. language
|
||||||
|
const value = params.length ? params.shift().toLowerCase() : 'all'; //ex. en_us --> combined: -component reload language en_us
|
||||||
|
|
||||||
|
if (name === 'language' || name === 'lang' || name === 'l') {
|
||||||
|
|
||||||
|
if (value === 'all') {
|
||||||
|
this.client.localeLoader.loadLanguages();
|
||||||
|
return { msg: 'Reloaded all languages' };
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
this.client.localeLoader.loadLanguage(value);
|
||||||
|
return { msg: `Reloaded locale \`${value}\`` };
|
||||||
|
} catch (err) {
|
||||||
|
return { error: true, msg: err.message };
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (name === 'all') {
|
||||||
|
|
||||||
|
const errors = [];
|
||||||
|
const components = this.client.registry.components;
|
||||||
|
for (let component of components.values()) {
|
||||||
|
const result = component.reload();
|
||||||
|
if (result.error) errors.push(`Component ${component.id} errored while reloading with code \`${result.code}\``);
|
||||||
|
}
|
||||||
|
if (errors.length) return { error: true, msg: `The following errors occurred during reload:\n${errors.join('\n')}` };
|
||||||
|
return { msg: `Successfully reloaded all components` };
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
const component = this.client.registry.components.get(name);
|
||||||
|
if (!component) return { error: true, msg: `Component ${name} doesn't exist.` };
|
||||||
|
const result = component.reload();
|
||||||
|
if (result.error) return { error: true, msg: `Component ${name} errored while reloading with code \`${result.code}\`` };
|
||||||
|
else return { msg: `Successfully reloaded ${name}` };
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_handleDisableEnable(name, enable) {
|
||||||
|
|
||||||
|
const component = this.client.registry.components.get(name);
|
||||||
|
let result;
|
||||||
|
if (!component) return { error: true, msg: `Component ${name} doesn't exist.` };
|
||||||
|
if (enable) result = component.enable();
|
||||||
|
else result = component.disable();
|
||||||
|
|
||||||
|
if (result.error) return { error: true, msg: `Cannot ${enable ? 'enable' : 'disable'} ${name} due to ${result.code}` };
|
||||||
|
else return { msg: `Successfully ${enable ? 'enabled' : 'disabled'} component ${name}` };
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_handleLoadUnload(name, load) {
|
||||||
|
|
||||||
|
let result;
|
||||||
|
if (load) {
|
||||||
|
const directory = path.join(process.cwd(), 'structure/client/components', name);
|
||||||
|
try {
|
||||||
|
fs.accessSync(directory);
|
||||||
|
} catch(err) {
|
||||||
|
return { error: true, msg: `\`${name}\` is an invalid path!` };
|
||||||
|
}
|
||||||
|
// components/commands/utility/Ping.js
|
||||||
|
const func = require(directory); //directory
|
||||||
|
if (typeof func !== 'function') {
|
||||||
|
delete require.cache[directory];
|
||||||
|
return { error: true, msg: 'Attempted to index an invalid function as a component.' };
|
||||||
|
}
|
||||||
|
const component = new func(this.client);
|
||||||
|
result = this.client.registry.loadComponent(component, directory);
|
||||||
|
if (!result) return { error: true, msg: `Failed to load component ${name}, see console.` };
|
||||||
|
return { msg: `Successfully loaded component: ${component.resolveable}` };
|
||||||
|
|
||||||
|
} else {
|
||||||
|
const component = this.client.registry.components.filter(filterInexact(name)).first();
|
||||||
|
if (!component) return { error: true, msg: `Component ${name} doesn't exist.` };
|
||||||
|
result = component.unload();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.error) return { error: true, msg: `Cannot ${load ? 'load' : 'unload'} ${name} due to ${result.code}` };
|
||||||
|
else return { msg: `Successfully ${load ? 'loaded' : 'unloaded'} component ${name}` };
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ComponentCommand;
|
||||||
|
|
||||||
|
const filterInexact = (search) => {
|
||||||
|
return comp => comp.id.toLowerCase().includes(search) ||
|
||||||
|
comp.resolveable.toLowerCase().includes(search) ||
|
||||||
|
(comp.aliases && (comp.aliases.some(ali => `${comp.type}:${ali}`.toLowerCase().includes(search)) ||
|
||||||
|
comp.aliases.some(ali => ali.toLowerCase().includes(search))));
|
||||||
|
};
|
@ -18,8 +18,8 @@ class Evaluate extends Command {
|
|||||||
'eval',
|
'eval',
|
||||||
'e'
|
'e'
|
||||||
],
|
],
|
||||||
|
usage: '<code>',
|
||||||
restricted: true,
|
restricted: true,
|
||||||
description: "Evaluates javascript code.",
|
|
||||||
arguments: [
|
arguments: [
|
||||||
new Argument(client, {
|
new Argument(client, {
|
||||||
name: 'log',
|
name: 'log',
|
||||||
@ -33,12 +33,12 @@ class Evaluate extends Command {
|
|||||||
types: ['FLAG'],
|
types: ['FLAG'],
|
||||||
description: "Hides the output from the channel."
|
description: "Hides the output from the channel."
|
||||||
})
|
})
|
||||||
]
|
],
|
||||||
|
showUsage: true
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async execute(message, { params, args }) {
|
async execute(message, { params, args }) {
|
||||||
|
|
||||||
params = params.join(' ');
|
params = params.join(' ');
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
const { Command, Argument } = require('../../../../interfaces/');
|
|
||||||
|
|
||||||
class ReloadCommand extends Command {
|
|
||||||
|
|
||||||
constructor(client) {
|
|
||||||
|
|
||||||
super(client, {
|
|
||||||
name: 'reload',
|
|
||||||
module: 'developer',
|
|
||||||
description: 'Reloads components and locales.',
|
|
||||||
restricted: true,
|
|
||||||
aliases: ['r'],
|
|
||||||
arguments: [
|
|
||||||
new Argument(client, {
|
|
||||||
name: 'language',
|
|
||||||
type: 'STRING',
|
|
||||||
types: ['FLAG'],
|
|
||||||
aliases: [ 'lang' ],
|
|
||||||
description: "Reloads the language library",
|
|
||||||
default: 'all'
|
|
||||||
})
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
this.client = client;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
async execute(message, { args }) {
|
|
||||||
|
|
||||||
if (args.language) {
|
|
||||||
if (args.language.value === 'all') {
|
|
||||||
await this.client.localeLoader.loadLanguages();
|
|
||||||
return message.respond('Reloaded all languages');
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
await this.client.localeLoader.loadLanguage(args.language.value);
|
|
||||||
return message.respond(`Reloaded locale \`${args.language.value}\``);
|
|
||||||
} catch (err) {
|
|
||||||
return message.respond(err.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = ReloadCommand;
|
|
110
structure/client/components/commands/information/Commands.js
Normal file
110
structure/client/components/commands/information/Commands.js
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
const { Command } = require('../../../../interfaces/');
|
||||||
|
|
||||||
|
class CommandsCommand extends Command {
|
||||||
|
|
||||||
|
constructor(client) {
|
||||||
|
|
||||||
|
super(client, {
|
||||||
|
name: 'commands',
|
||||||
|
module: 'information',
|
||||||
|
aliases: [
|
||||||
|
'cmd',
|
||||||
|
'cmds',
|
||||||
|
'command'
|
||||||
|
],
|
||||||
|
usage: '[module]',
|
||||||
|
arguments: [
|
||||||
|
// new Argument(client, {
|
||||||
|
// name: 'user',
|
||||||
|
// type: 'BOOLEAN',
|
||||||
|
// types: ['VERBAL', 'FLAG'],
|
||||||
|
// default: true
|
||||||
|
// }),
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
this.client = client;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async execute(message, { params }) {
|
||||||
|
|
||||||
|
if (!params.length) // list all commands
|
||||||
|
return this._listCommands(message);
|
||||||
|
|
||||||
|
params = params.join(' ');
|
||||||
|
|
||||||
|
const [ mod ] = this.client.resolver.components(params, 'module', false);
|
||||||
|
if(!mod) {
|
||||||
|
const [ command ] = this.client.resolver.components(params, 'command', false);
|
||||||
|
if (!command) return message.format('C_COMMAND_INVALID');
|
||||||
|
return await message._showUsage(command);
|
||||||
|
}
|
||||||
|
//list module's commands
|
||||||
|
|
||||||
|
const commands = mod.components.filter(c=>c.type === 'command');
|
||||||
|
let text = '';
|
||||||
|
|
||||||
|
for(let command of commands.values()) {
|
||||||
|
text += command.disabled ? `~~${command.name}~~\n` : `${command.name}`; //TODO: Denote disabled commands somehow
|
||||||
|
}
|
||||||
|
|
||||||
|
const embed = {
|
||||||
|
author: {
|
||||||
|
name: message.format('C_COMMANDS_TITLE'),
|
||||||
|
icon_url: this.client.user.avatarURL()
|
||||||
|
},
|
||||||
|
description: message.format('C_COMMANDS') + '\n' + message.format('C_COMMANDS_TEMPLATE', { mod: mod.name, text }),
|
||||||
|
footer: {
|
||||||
|
text: message.format('C_COMMANDS_FOOTER')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return message.embed(embed);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_listCommands(message) {
|
||||||
|
|
||||||
|
let fields = [];
|
||||||
|
const sortedModules = this.client.registry.components
|
||||||
|
.filter(c => c.type === 'module')
|
||||||
|
.sort((a, b) => {
|
||||||
|
const filter = c => c.type === 'command';
|
||||||
|
return b.components.filter(filter) - a.components.filter(filter);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const mod of sortedModules.values()) {
|
||||||
|
let field = {
|
||||||
|
name: mod.id,
|
||||||
|
value: '',
|
||||||
|
inline: true
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const command of mod.components.values()) {
|
||||||
|
if (command.type !== 'command'
|
||||||
|
|| (command.restricted && !this.client._options.bot.owners.includes(message.author.id))) continue;
|
||||||
|
field.value += `${command.name}\n`;
|
||||||
|
}
|
||||||
|
if (field.value) fields.push(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
const embed = {
|
||||||
|
author: {
|
||||||
|
name: message.format('C_COMMANDS_TITLE'),
|
||||||
|
icon_url: this.client.user.avatarURL()
|
||||||
|
},
|
||||||
|
description: message.format('C_COMMANDS'),
|
||||||
|
fields,
|
||||||
|
footer: {
|
||||||
|
text: message.format('C_COMMANDS_FOOTER')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return message.embed(embed);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = CommandsCommand;
|
@ -6,18 +6,20 @@ class HelpCommand extends Command {
|
|||||||
|
|
||||||
super(client, {
|
super(client, {
|
||||||
name: 'help',
|
name: 'help',
|
||||||
module: 'information',
|
module: 'information'
|
||||||
description: 'Get help!',
|
|
||||||
showUsage: true
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.client = client;
|
this.client = client;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(message, { params }) {
|
async execute(message, { params }) {
|
||||||
|
|
||||||
|
if (!params.length)
|
||||||
|
return await message.embed({
|
||||||
|
description: message.format('C_HELP')
|
||||||
|
});
|
||||||
|
|
||||||
const [ key ] = params;
|
const [ key ] = params;
|
||||||
let [ result ] = this.client.resolver.components(key, 'command');
|
let [ result ] = this.client.resolver.components(key, 'command');
|
||||||
if (!result) [ result ] = this.client.resolver.components(key, 'setting');
|
if (!result) [ result ] = this.client.resolver.components(key, 'setting');
|
||||||
|
@ -9,7 +9,6 @@ class PingCommand extends Command {
|
|||||||
super(client, {
|
super(client, {
|
||||||
name: 'arguments',
|
name: 'arguments',
|
||||||
module: 'utility',
|
module: 'utility',
|
||||||
description: "Tests the argument parsing of the command handler.",
|
|
||||||
aliases: ['args', 'arg', 'argument'],
|
aliases: ['args', 'arg', 'argument'],
|
||||||
arguments: [
|
arguments: [
|
||||||
new Argument(client, {
|
new Argument(client, {
|
||||||
@ -32,7 +31,9 @@ class PingCommand extends Command {
|
|||||||
required: true,
|
required: true,
|
||||||
types: ['FLAG', 'VERBAL']
|
types: ['FLAG', 'VERBAL']
|
||||||
})
|
})
|
||||||
]
|
],
|
||||||
|
restricted: true,
|
||||||
|
archivable: false
|
||||||
});
|
});
|
||||||
|
|
||||||
this.client = client;
|
this.client = client;
|
||||||
|
@ -28,9 +28,7 @@ class SettingCommand extends Command {
|
|||||||
default: true
|
default: true
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
memberPermissions: ['ADMINISTRATOR'],
|
showUsage: true
|
||||||
showUsage: true,
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.client = client;
|
this.client = client;
|
||||||
@ -67,17 +65,16 @@ class SettingCommand extends Command {
|
|||||||
|
|
||||||
//Setting permission handling
|
//Setting permission handling
|
||||||
if(setting.clientPermissions.length > 0) {
|
if(setting.clientPermissions.length > 0) {
|
||||||
const missing = message.channel.permissionsFor(message.guild.me).missing(command.clientPermissions);
|
const missing = message.channel.permissionsFor(message.guild.me).missing(setting.clientPermissions);
|
||||||
if(missing.length > 0) {
|
if(missing.length > 0) {
|
||||||
await message.respond(message.format('C_SETTINGS_CLIENTPERMISSIONERROR', { setting: setting.moduleResolveable, missing: missing.join(', ')}), { emoji: 'failure' });
|
await message.respond(message.format('C_SETTINGS_CLIENTPERMISSIONERROR', { setting: setting.moduleResolveable, missing: missing.join(', ')}), { emoji: 'failure' });
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
} else if(setting.memberPermissions.length > 0) {
|
}
|
||||||
const missing = message.channel.permissionsFor(message.member).missing(command.memberPermissions);
|
|
||||||
if(missing.length > 0) {
|
if(message.channel.permissionsFor(message.member).missing('ADMINISTRATOR').length > 0 && setting.resolve === 'GUILD') {
|
||||||
await message.respond(message.format('C_SETTINGS_MEMBERPERMISSIONERROR', { setting: setting.moduleResolveable, missing: missing.join(', ')}), { emoji: 'failure' });
|
await message.respond(message.format('C_SETTINGS_ADMINISTRATORERROR', { type: type.toLowerCase() }), { emoji: 'failure' });
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await setting.handle(message, params.splice(1));
|
const response = await setting.handle(message, params.splice(1));
|
||||||
@ -138,8 +135,8 @@ class SettingCommand extends Command {
|
|||||||
if(!bool) return message.respond(message.format('C_SETTINGS_RESETABORT'), { emoji: 'success' });
|
if(!bool) return message.respond(message.format('C_SETTINGS_RESETABORT'), { emoji: 'success' });
|
||||||
|
|
||||||
type === 'USER'
|
type === 'USER'
|
||||||
? await message.author._deleteSettings()
|
? await message.author._delete()
|
||||||
: await message.guild._deleteSettings();
|
: await message.guild._delete('guilds');
|
||||||
|
|
||||||
return message.respond(message.format('C_SETTINGS_RESETSUCCESS', { type: type.toLowerCase() }), { emoji: 'success' })
|
return message.respond(message.format('C_SETTINGS_RESETSUCCESS', { type: type.toLowerCase() }), { emoji: 'success' })
|
||||||
|
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
const { Command } = require('../../../../interfaces/');
|
|
||||||
|
|
||||||
class PingCommand extends Command {
|
|
||||||
|
|
||||||
constructor(client) {
|
|
||||||
|
|
||||||
super(client, {
|
|
||||||
name: 'test',
|
|
||||||
module: 'utility',
|
|
||||||
description: "Determines the ping of the bot.",
|
|
||||||
arguments: [
|
|
||||||
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
this.client = client;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
async execute(message) {
|
|
||||||
|
|
||||||
const time1 = new Date().getTime();
|
|
||||||
let response = await this.client.transactionHandler.send({ provider: 'mongodb', request: { collection: 'infractions', type: 'find', query: { case: 1 } } }).catch(err => { return err; });
|
|
||||||
const time2 = new Date().getTime();
|
|
||||||
console.log(time2-time1);
|
|
||||||
|
|
||||||
message.reply(JSON.stringify(response));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = PingCommand;
|
|
@ -10,30 +10,37 @@ const Guild = Structures.extend('Guild', (Guild) => {
|
|||||||
super(...args);
|
super(...args);
|
||||||
|
|
||||||
this._settings = null; //internal cache of current guild's settings; should ALWAYS stay the same as database.
|
this._settings = null; //internal cache of current guild's settings; should ALWAYS stay the same as database.
|
||||||
|
this._permissions = null; //internal cache, should always match database.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async settings() {
|
async settings() {
|
||||||
|
|
||||||
if(!this._settings) this._settings = this.client.transactionHandler.send({ provider: 'mongodb', request: { collection: 'guilds', type: 'findOne', query: { guildId: this.id } } });
|
if(!this._settings) this._settings = this.client.transactionHandler.send({ provider: 'mongodb', request: { collection: 'guilds', type: 'findOne', query: { guildId: this.id } } });
|
||||||
if(this._settings instanceof Promise) this._settings = await this._settings || null
|
if(this._settings instanceof Promise) this._settings = await this._settings || null;
|
||||||
if(!this._settings) {
|
if(!this._settings) {
|
||||||
this._settings = this.client.defaultConfig;
|
this._settings = this.client.defaultConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._settings;
|
return this._settings;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Database Shortcuts */
|
async permissions_() {
|
||||||
|
if(!this._permissions) this._permissions = this.client.transactionHandler.send({ provider: 'mongodb', request: { collection: 'permissions', type: 'findOne', query: { guildId: this.id } } });
|
||||||
|
if(this._permissions instanceof Promise) this._permissions = await this._permissions || null;
|
||||||
|
if(!this._permissions) {
|
||||||
|
this._permissions = {};
|
||||||
|
}
|
||||||
|
return this._permissions;
|
||||||
|
}
|
||||||
|
|
||||||
async _deleteSettings() { //Delete whole entry - remove
|
/* Settings Wrapper */
|
||||||
|
|
||||||
|
async _dbDelete(collection) { //Delete whole entry - remove
|
||||||
try {
|
try {
|
||||||
await this.client.transactionHandler.send({
|
await this.client.transactionHandler.send({
|
||||||
provider: 'mongodb',
|
provider: 'mongodb',
|
||||||
request: {
|
request: {
|
||||||
type: 'remove',
|
type: 'remove',
|
||||||
collection: 'guilds',
|
collection,
|
||||||
query: {
|
query: {
|
||||||
guildId: this.id
|
guildId: this.id
|
||||||
}
|
}
|
||||||
@ -46,21 +53,22 @@ const Guild = Structures.extend('Guild', (Guild) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _updateSettings(data) { //Update property (upsert true) - updateOne
|
async _dbUpdateOne(data, collection) { //Update property (upsert true) - updateOne
|
||||||
|
var index = this.dbIndex(collection);
|
||||||
try {
|
try {
|
||||||
await this.client.transactionHandler.send({
|
await this.client.transactionHandler.send({
|
||||||
provider: 'mongodb',
|
provider: 'mongodb',
|
||||||
request: {
|
request: {
|
||||||
type: 'updateOne',
|
type: 'updateOne',
|
||||||
collection: 'guilds',
|
collection,
|
||||||
query: {
|
query: {
|
||||||
guildId: this.id
|
guildId: this.id
|
||||||
},
|
},
|
||||||
data
|
data
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this._settings = {
|
index = {
|
||||||
...this._settings,
|
...index,
|
||||||
...data
|
...data
|
||||||
};
|
};
|
||||||
this._storageLog(`Database Update (guild:${this.id}).`);
|
this._storageLog(`Database Update (guild:${this.id}).`);
|
||||||
@ -69,18 +77,18 @@ const Guild = Structures.extend('Guild', (Guild) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _removeSettings(value) { //Remove property
|
async _dbRemoveProperty(value, collection) { //Remove property
|
||||||
if(this.client.defaultConfig[value]) {
|
const index = this.dbIndex(collection);
|
||||||
|
if(collection === 'guild' && this.client.defaultConfig[value]) {
|
||||||
await this._updateSettings(this.client.defaultConfig[value]);
|
await this._updateSettings(this.client.defaultConfig[value]);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.client.transactionHandler.send({
|
await this.client.transactionHandler.send({
|
||||||
provider: 'mongodb',
|
provider: 'mongodb',
|
||||||
request: {
|
request: {
|
||||||
type: 'removeProperty',
|
type: 'removeProperty',
|
||||||
collection: 'guilds',
|
collection,
|
||||||
query: {
|
query: {
|
||||||
guildId: this.id
|
guildId: this.id
|
||||||
},
|
},
|
||||||
@ -89,33 +97,23 @@ const Guild = Structures.extend('Guild', (Guild) => {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
delete this._settings[value];
|
delete index[value];
|
||||||
this._storageLog(`Database Remove (guild:${this.id}).`);
|
this._storageLog(`Database Remove (guild:${this.id}).`);
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
this._storageError(error);
|
this._storageError(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
dbIndex(collection) {
|
||||||
async _createSettings(data) {
|
return {
|
||||||
try {
|
'guilds': this._settings,
|
||||||
this.client.transactionHandler.send({
|
'permissions': this._permissions
|
||||||
provider: 'mongodb',
|
}[collection];
|
||||||
request: {
|
|
||||||
type: 'insertOne',
|
|
||||||
collection: 'guilds',
|
|
||||||
data: {
|
|
||||||
guildId: this.id,
|
|
||||||
...data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this._storageLog(`Database Create (guild:${this.id}).`);
|
|
||||||
} catch(error) {
|
|
||||||
this._storageError(error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
/* Permissions Wrapper */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Language Formatting */
|
/* Language Formatting */
|
||||||
|
|
||||||
|
26
structure/extensions/GuildMember.js
Normal file
26
structure/extensions/GuildMember.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
const { Structures } = require('discord.js');
|
||||||
|
|
||||||
|
const GuildMember = Structures.extend('GuildMember', (GuildMember) => {
|
||||||
|
|
||||||
|
class ExtendedGuildMember extends GuildMember {
|
||||||
|
|
||||||
|
constructor(...args) {
|
||||||
|
|
||||||
|
super(...args);
|
||||||
|
|
||||||
|
this._cached = Date.now();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
get timeSinceCached() {
|
||||||
|
return Date.now()-this._cached;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return ExtendedGuildMember;
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = GuildMember;
|
@ -4,6 +4,7 @@ const escapeRegex = require('escape-string-regexp');
|
|||||||
const emojis = require('../../util/emojis.json');
|
const emojis = require('../../util/emojis.json');
|
||||||
|
|
||||||
const { Util } = require('../../util/');
|
const { Util } = require('../../util/');
|
||||||
|
const { stripIndents } = require('common-tags')
|
||||||
|
|
||||||
const Message = Structures.extend('Message', (Message) => {
|
const Message = Structures.extend('Message', (Message) => {
|
||||||
|
|
||||||
@ -26,7 +27,7 @@ const Message = Structures.extend('Message', (Message) => {
|
|||||||
let language = this.author._settings.locale || 'en_us';
|
let language = this.author._settings.locale || 'en_us';
|
||||||
if(this.guild && this.guild._settings.locale) language = this.guild._settings.locale;
|
if(this.guild && this.guild._settings.locale) language = this.guild._settings.locale;
|
||||||
|
|
||||||
parameters.prefix = this.guild ? this.guild.prefix : this.client._options.bot.prefix;
|
parameters.prefix = this.guild?.prefix || this.client._options.bot.prefix;
|
||||||
let template = this.client.localeLoader.template(language, index); //.languages[language][index];
|
let template = this.client.localeLoader.template(language, index); //.languages[language][index];
|
||||||
|
|
||||||
if(!template) {
|
if(!template) {
|
||||||
@ -118,18 +119,46 @@ const Message = Structures.extend('Message', (Message) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async _showUsage() {
|
async _showUsage(comp = null) {
|
||||||
//TODO: format this
|
|
||||||
return await this.embed({
|
const component = comp
|
||||||
title: `**${this.command.name.toUpperCase()} USAGE**`,
|
? comp
|
||||||
description: this.format(`C_${this.command.name.toUpperCase()}_USAGE`),
|
: this.command;
|
||||||
fields: [
|
|
||||||
{
|
const prefix = this.guild?.prefix
|
||||||
name: this.format('EXAMPLES'),
|
|| this.client._options.bot.prefix;
|
||||||
value: this.format(`C_${this.command.name.toUpperCase()}_EXAMPLES`)
|
|
||||||
}
|
let fields = [];
|
||||||
]
|
if(component.examples.length > 0) {
|
||||||
});
|
fields.push({
|
||||||
|
name: `》${this.format('GENERAL_EXAMPLES')}`,
|
||||||
|
value: component.examples.map(e=>`\`${prefix}${component.name} ${e}\``).join('\n')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if(component.aliases.length > 0) {
|
||||||
|
fields.push({
|
||||||
|
name: `》${this.format('GENERAL_ALIASES')}`,
|
||||||
|
value: component.aliases.map(a=>`\`${a}\``).join(', ')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if(component.arguments.length > 0) {
|
||||||
|
fields.push({
|
||||||
|
name: `》${this.format('GENERAL_ARGUMENTS')}`,
|
||||||
|
value: component.arguments.map(a=>`${a.name}: ${this.format(`A_${a.name.toUpperCase}_DESCRIPTION`)}`)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let embed = {
|
||||||
|
author: {
|
||||||
|
name: `${component.name}${component.module ? ` (${component.module.resolveable})` : ''}`,
|
||||||
|
icon_url: this.client.user.avatarURL()
|
||||||
|
},
|
||||||
|
description: stripIndents`\`${prefix}${component.name}${component.usage ? ` ${component.usage}` : ''}\`
|
||||||
|
${this.format(`C_${component.name.toUpperCase()}_DESCRIPTION`)}${component.guildOnly ? ' *(guild-only)*' : ''}`,
|
||||||
|
fields
|
||||||
|
};
|
||||||
|
|
||||||
|
return await this.embed(embed);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
Message: require('./Message.js'),
|
Message: require('./Message.js'),
|
||||||
Guild: require('./Guild.js'),
|
Guild: require('./Guild.js'),
|
||||||
|
GuildMember: require('./GuildMember.js'),
|
||||||
User: require('./User.js')
|
User: require('./User.js')
|
||||||
};
|
};
|
@ -19,14 +19,15 @@ class Command extends Component {
|
|||||||
this.aliases = opts.aliases || [];
|
this.aliases = opts.aliases || [];
|
||||||
|
|
||||||
this.description = `C_${opts.name}_DESCRIPTION`;
|
this.description = `C_${opts.name}_DESCRIPTION`;
|
||||||
this.examples = `C_${opts.name}_EXAMPLES`;
|
this.usage = opts.usage || '';
|
||||||
this.usage = `C_${opts.name}_USAGE`;
|
this.examples = opts.examples || [];
|
||||||
|
|
||||||
this.restricted = Boolean(opts.restricted);
|
this.restricted = Boolean(opts.restricted);
|
||||||
this.archivable = opts.archivable === undefined ? false : Boolean(opts.archivable);
|
|
||||||
this.guildOnly = Boolean(opts.guildOnly);
|
|
||||||
this.arguments = opts.arguments || [];
|
|
||||||
this.showUsage = Boolean(opts.showUsage);
|
this.showUsage = Boolean(opts.showUsage);
|
||||||
|
this.guildOnly = Boolean(opts.guildOnly);
|
||||||
|
|
||||||
|
this.archivable = opts.archivable === undefined ? false : Boolean(opts.archivable);
|
||||||
|
this.arguments = opts.arguments || [];
|
||||||
|
|
||||||
this.clientPermissions = opts.clientPermissions || [];
|
this.clientPermissions = opts.clientPermissions || [];
|
||||||
this.memberPermissions = opts.memberPermissions || [];
|
this.memberPermissions = opts.memberPermissions || [];
|
||||||
|
@ -41,15 +41,8 @@ class Setting extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async _parseArguments(params) {
|
async _parseArguments(params) {
|
||||||
|
|
||||||
const { parsedArguments, newArgs } = await this.commandHandler._parseArguments(this.arguments, params);
|
const { parsedArguments, newArgs } = await this.commandHandler._parseArguments(this.arguments, params);
|
||||||
return { parsedArguments, params: newArgs };
|
return { parsedArguments, params: newArgs };
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
async _handleReset(message, params) {
|
|
||||||
const response = await message.prompt(message.format('UHHH'), { error: 'warning' });
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get commandHandler() {
|
get commandHandler() {
|
||||||
|
Loading…
Reference in New Issue
Block a user