mirror of
https://github.com/danbulant/Shasha
synced 2026-07-08 04:21:06 +00:00
moved
This commit is contained in:
parent
7eb0f91e20
commit
013860d988
13 changed files with 682 additions and 3 deletions
2
Main.js
2
Main.js
|
|
@ -23,6 +23,7 @@ const { timestampAt } = require("./resources/debug");
|
||||||
const requireAll = require("require-all");
|
const requireAll = require("require-all");
|
||||||
|
|
||||||
const lgr = requireAll({ dirname: join(__dirname, "resources/eventsLogger"), recursive: true });
|
const lgr = requireAll({ dirname: join(__dirname, "resources/eventsLogger"), recursive: true });
|
||||||
|
client.functions = requireAll({ dirname: join(__dirname, "../../resources"), recursive: true });
|
||||||
|
|
||||||
client.registry
|
client.registry
|
||||||
.registerGroups([
|
.registerGroups([
|
||||||
|
|
@ -34,7 +35,6 @@ client.registry
|
||||||
"profile",
|
"profile",
|
||||||
"owner"
|
"owner"
|
||||||
])
|
])
|
||||||
.registerDefaults()
|
|
||||||
.registerCommandsIn(join(__dirname, 'cmds'));
|
.registerCommandsIn(join(__dirname, 'cmds'));
|
||||||
|
|
||||||
client.setProvider(
|
client.setProvider(
|
||||||
|
|
|
||||||
49
cmds/owner/disable.js
Normal file
49
cmds/owner/disable.js
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
const { oneLine } = require('common-tags');
|
||||||
|
const Command = require('../../node_modules/@iceprod/discord.js-commando/src/commands/base');
|
||||||
|
|
||||||
|
module.exports = class DisableCommandCommand extends Command {
|
||||||
|
constructor(client) {
|
||||||
|
super(client, {
|
||||||
|
name: 'disable',
|
||||||
|
aliases: ['disable-command', 'cmd-off', 'command-off'],
|
||||||
|
group: 'commands',
|
||||||
|
memberName: 'disable',
|
||||||
|
description: 'Disables a command or command group.',
|
||||||
|
details: oneLine`
|
||||||
|
The argument must be the name/ID (partial or whole) of a command or command group.
|
||||||
|
Only administrators may use this command.
|
||||||
|
`,
|
||||||
|
examples: ['disable util', 'disable Utility', 'disable prefix'],
|
||||||
|
guarded: true,
|
||||||
|
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
key: 'cmdOrGrp',
|
||||||
|
label: 'command/group',
|
||||||
|
prompt: 'Which command or group would you like to disable?',
|
||||||
|
type: 'group|command'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
hasPermission(msg) {
|
||||||
|
if (!msg.guild) return this.client.isOwner(msg.author);
|
||||||
|
return msg.member.permissions.has('ADMINISTRATOR') || this.client.isOwner(msg.author);
|
||||||
|
}
|
||||||
|
|
||||||
|
run(msg, args) {
|
||||||
|
if (!args.cmdOrGrp.isEnabledIn(msg.guild, true)) {
|
||||||
|
return msg.reply(
|
||||||
|
`The \`${args.cmdOrGrp.name}\` ${args.cmdOrGrp.group ? 'command' : 'group'} is already disabled.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (args.cmdOrGrp.guarded) {
|
||||||
|
return msg.reply(
|
||||||
|
`You cannot disable the \`${args.cmdOrGrp.name}\` ${args.cmdOrGrp.group ? 'command' : 'group'}.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
args.cmdOrGrp.setEnabledIn(msg.guild, false);
|
||||||
|
return msg.reply(`Disabled the \`${args.cmdOrGrp.name}\` ${args.cmdOrGrp.group ? 'command' : 'group'}.`);
|
||||||
|
}
|
||||||
|
};
|
||||||
55
cmds/owner/enable.js
Normal file
55
cmds/owner/enable.js
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
const { oneLine } = require('common-tags');
|
||||||
|
const Command = require('../../node_modules/@iceprod/discord.js-commando/src/commands/base');
|
||||||
|
|
||||||
|
module.exports = class EnableCommandCommand extends Command {
|
||||||
|
constructor(client) {
|
||||||
|
super(client, {
|
||||||
|
name: 'enable',
|
||||||
|
aliases: ['enable-command', 'cmd-on', 'command-on'],
|
||||||
|
group: 'commands',
|
||||||
|
memberName: 'enable',
|
||||||
|
description: 'Enables a command or command group.',
|
||||||
|
details: oneLine`
|
||||||
|
The argument must be the name/ID (partial or whole) of a command or command group.
|
||||||
|
Only administrators may use this command.
|
||||||
|
`,
|
||||||
|
examples: ['enable util', 'enable Utility', 'enable prefix'],
|
||||||
|
guarded: true,
|
||||||
|
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
key: 'cmdOrGrp',
|
||||||
|
label: 'command/group',
|
||||||
|
prompt: 'Which command or group would you like to enable?',
|
||||||
|
type: 'group|command'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
hasPermission(msg) {
|
||||||
|
if(!msg.guild) return this.client.isOwner(msg.author);
|
||||||
|
return msg.member.permissions.has('ADMINISTRATOR') || this.client.isOwner(msg.author);
|
||||||
|
}
|
||||||
|
|
||||||
|
run(msg, args) {
|
||||||
|
const group = args.cmdOrGrp.group;
|
||||||
|
if(args.cmdOrGrp.isEnabledIn(msg.guild, true)) {
|
||||||
|
return msg.reply(
|
||||||
|
`The \`${args.cmdOrGrp.name}\` ${args.cmdOrGrp.group ? 'command' : 'group'} is already enabled${
|
||||||
|
group && !group.isEnabledIn(msg.guild) ?
|
||||||
|
`, but the \`${group.name}\` group is disabled, so it still can't be used` :
|
||||||
|
''
|
||||||
|
}.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
args.cmdOrGrp.setEnabledIn(msg.guild, true);
|
||||||
|
return msg.reply(
|
||||||
|
`Enabled the \`${args.cmdOrGrp.name}\` ${group ? 'command' : 'group'}${
|
||||||
|
group && !group.isEnabledIn(msg.guild) ?
|
||||||
|
`, but the \`${group.name}\` group is disabled, so it still can't be used` :
|
||||||
|
''
|
||||||
|
}.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
116
cmds/owner/eval.js
Normal file
116
cmds/owner/eval.js
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
const util = require('util');
|
||||||
|
const discord = require('discord.js');
|
||||||
|
const tags = require('common-tags');
|
||||||
|
const { escapeRegex } = require('../../node_modules/@iceprod/discord.js-commando/src/util');
|
||||||
|
const Command = require('../../node_modules/@iceprod/discord.js-commando/src/commands/base');
|
||||||
|
|
||||||
|
const nl = '!!NL!!';
|
||||||
|
const nlPattern = new RegExp(nl, 'g');
|
||||||
|
|
||||||
|
module.exports = class EvalCommand extends Command {
|
||||||
|
constructor(client) {
|
||||||
|
super(client, {
|
||||||
|
name: 'eval',
|
||||||
|
group: 'util',
|
||||||
|
memberName: 'eval',
|
||||||
|
description: 'Executes JavaScript code.',
|
||||||
|
details: 'Only the bot owner(s) may use this command.',
|
||||||
|
ownerOnly: true,
|
||||||
|
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
key: 'script',
|
||||||
|
prompt: 'What code would you like to evaluate?',
|
||||||
|
type: 'string'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
this.lastResult = null;
|
||||||
|
Object.defineProperty(this, '_sensitivePattern', { value: null, configurable: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
run(msg, args) {
|
||||||
|
// Make a bunch of helpers
|
||||||
|
/* eslint-disable no-unused-vars */
|
||||||
|
const message = msg;
|
||||||
|
const client = msg.client;
|
||||||
|
const lastResult = this.lastResult;
|
||||||
|
const doReply = val => {
|
||||||
|
if (val instanceof Error) {
|
||||||
|
msg.reply(`Callback error: \`${val}\``);
|
||||||
|
} else {
|
||||||
|
const result = this.makeResultMessages(val, process.hrtime(this.hrStart));
|
||||||
|
if (Array.isArray(result)) {
|
||||||
|
for (const item of result) msg.reply(item);
|
||||||
|
} else {
|
||||||
|
msg.reply(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/* eslint-enable no-unused-vars */
|
||||||
|
|
||||||
|
// Remove any surrounding code blocks before evaluation
|
||||||
|
if (args.script.startsWith('```') && args.script.endsWith('```')) {
|
||||||
|
args.script = args.script.replace(/(^.*?\s)|(\n.*$)/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the code and measure its execution time
|
||||||
|
let hrDiff;
|
||||||
|
try {
|
||||||
|
const hrStart = process.hrtime();
|
||||||
|
this.lastResult = eval(args.script);
|
||||||
|
hrDiff = process.hrtime(hrStart);
|
||||||
|
} catch (err) {
|
||||||
|
return msg.reply(`Error while evaluating: \`${err}\``);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare for callback time and respond
|
||||||
|
this.hrStart = process.hrtime();
|
||||||
|
const result = this.makeResultMessages(this.lastResult, hrDiff, args.script);
|
||||||
|
if (Array.isArray(result)) {
|
||||||
|
return result.map(item => msg.reply(item));
|
||||||
|
} else {
|
||||||
|
return msg.reply(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
makeResultMessages(result, hrDiff, input = null) {
|
||||||
|
const inspected = util.inspect(result, { depth: 0 })
|
||||||
|
.replace(nlPattern, '\n')
|
||||||
|
.replace(this.sensitivePattern, '--snip--');
|
||||||
|
const split = inspected.split('\n');
|
||||||
|
const last = inspected.length - 1;
|
||||||
|
const prependPart = inspected[0] !== '{' && inspected[0] !== '[' && inspected[0] !== "'" ? split[0] : inspected[0];
|
||||||
|
const appendPart = inspected[last] !== '}' && inspected[last] !== ']' && inspected[last] !== "'" ?
|
||||||
|
split[split.length - 1] :
|
||||||
|
inspected[last];
|
||||||
|
const prepend = `\`\`\`javascript\n${prependPart}\n`;
|
||||||
|
const append = `\n${appendPart}\n\`\`\``;
|
||||||
|
if (input) {
|
||||||
|
return discord.splitMessage(tags.stripIndents`
|
||||||
|
*Executed in ${hrDiff[0] > 0 ? `${hrDiff[0]}s ` : ''}${hrDiff[1] / 1000000}ms.*
|
||||||
|
\`\`\`javascript
|
||||||
|
${inspected}
|
||||||
|
\`\`\`
|
||||||
|
`, { maxLength: 2000, prepend, append });
|
||||||
|
} else {
|
||||||
|
return discord.splitMessage(tags.stripIndents`
|
||||||
|
*Callback executed after ${hrDiff[0] > 0 ? `${hrDiff[0]}s ` : ''}${hrDiff[1] / 1000000}ms.*
|
||||||
|
\`\`\`javascript
|
||||||
|
${inspected}
|
||||||
|
\`\`\`
|
||||||
|
`, { maxLength: 2000, prepend, append });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get sensitivePattern() {
|
||||||
|
if (!this._sensitivePattern) {
|
||||||
|
const client = this.client;
|
||||||
|
let pattern = '';
|
||||||
|
if (client.token) pattern += escapeRegex(client.token);
|
||||||
|
Object.defineProperty(this, '_sensitivePattern', { value: new RegExp(pattern, 'gi'), configurable: false });
|
||||||
|
}
|
||||||
|
return this._sensitivePattern;
|
||||||
|
}
|
||||||
|
};
|
||||||
30
cmds/owner/groups.js
Normal file
30
cmds/owner/groups.js
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
const { stripIndents } = require('common-tags');
|
||||||
|
const Command = require('../../node_modules/@iceprod/discord.js-commando/src/commands/base');
|
||||||
|
|
||||||
|
module.exports = class ListGroupsCommand extends Command {
|
||||||
|
constructor(client) {
|
||||||
|
super(client, {
|
||||||
|
name: 'groups',
|
||||||
|
aliases: ['list-groups', 'show-groups'],
|
||||||
|
group: 'commands',
|
||||||
|
memberName: 'groups',
|
||||||
|
description: 'Lists all command groups.',
|
||||||
|
details: 'Only administrators may use this command.',
|
||||||
|
guarded: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
hasPermission(msg) {
|
||||||
|
if(!msg.guild) return this.client.isOwner(msg.author);
|
||||||
|
return msg.member.permissions.has('ADMINISTRATOR') || this.client.isOwner(msg.author);
|
||||||
|
}
|
||||||
|
|
||||||
|
run(msg) {
|
||||||
|
return msg.reply(stripIndents`
|
||||||
|
__**Groups**__
|
||||||
|
${this.client.registry.groups.map(grp =>
|
||||||
|
`**${grp.name}:** ${grp.isEnabledIn(msg.guild) ? 'Enabled' : 'Disabled'}`
|
||||||
|
).join('\n')}
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
};
|
||||||
72
cmds/owner/load.js
Normal file
72
cmds/owner/load.js
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
const fs = require('fs');
|
||||||
|
const { oneLine } = require('common-tags');
|
||||||
|
const Command = require('../../node_modules/@iceprod/discord.js-commando/src/commands/base');
|
||||||
|
|
||||||
|
module.exports = class LoadCommandCommand extends Command {
|
||||||
|
constructor(client) {
|
||||||
|
super(client, {
|
||||||
|
name: 'load',
|
||||||
|
aliases: ['load-command'],
|
||||||
|
group: 'commands',
|
||||||
|
memberName: 'load',
|
||||||
|
description: 'Loads a new command.',
|
||||||
|
details: oneLine`
|
||||||
|
The argument must be full name of the command in the format of \`group:memberName\`.
|
||||||
|
Only the bot owner(s) may use this command.
|
||||||
|
`,
|
||||||
|
examples: ['load some-command'],
|
||||||
|
ownerOnly: true,
|
||||||
|
guarded: true,
|
||||||
|
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
key: 'command',
|
||||||
|
prompt: 'Which command would you like to load?',
|
||||||
|
validate: val => new Promise(resolve => {
|
||||||
|
if(!val) return resolve(false);
|
||||||
|
const split = val.split(':');
|
||||||
|
if(split.length !== 2) return resolve(false);
|
||||||
|
if(this.client.registry.findCommands(val).length > 0) {
|
||||||
|
return resolve('That command is already registered.');
|
||||||
|
}
|
||||||
|
const cmdPath = this.client.registry.resolveCommandPath(split[0], split[1]);
|
||||||
|
fs.access(cmdPath, fs.constants.R_OK, err => err ? resolve(false) : resolve(true));
|
||||||
|
return null;
|
||||||
|
}),
|
||||||
|
parse: val => {
|
||||||
|
const split = val.split(':');
|
||||||
|
const cmdPath = this.client.registry.resolveCommandPath(split[0], split[1]);
|
||||||
|
delete require.cache[cmdPath];
|
||||||
|
return require(cmdPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async run(msg, args) {
|
||||||
|
this.client.registry.registerCommand(args.command);
|
||||||
|
const command = this.client.registry.commands.last();
|
||||||
|
|
||||||
|
if(this.client.shard) {
|
||||||
|
try {
|
||||||
|
await this.client.shard.broadcastEval(`
|
||||||
|
const ids = [${this.client.shard.ids.join(',')}];
|
||||||
|
if(!this.shard.ids.some(id => ids.includes(id))) {
|
||||||
|
const cmdPath = this.registry.resolveCommandPath('${command.groupID}', '${command.name}');
|
||||||
|
delete require.cache[cmdPath];
|
||||||
|
this.registry.registerCommand(require(cmdPath));
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
} catch(err) {
|
||||||
|
this.client.emit('warn', `Error when broadcasting command load to other shards`);
|
||||||
|
this.client.emit('error', err);
|
||||||
|
await msg.reply(`Loaded \`${command.name}\` command, but failed to load on other shards.`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await msg.reply(`Loaded \`${command.name}\` command${this.client.shard ? ' on all shards' : ''}.`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
68
cmds/owner/reload.js
Normal file
68
cmds/owner/reload.js
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
const { oneLine } = require('common-tags');
|
||||||
|
const Command = require('../../node_modules/@iceprod/discord.js-commando/src/commands/base');
|
||||||
|
|
||||||
|
module.exports = class ReloadCommandCommand extends Command {
|
||||||
|
constructor(client) {
|
||||||
|
super(client, {
|
||||||
|
name: 'reload',
|
||||||
|
aliases: ['reload-command'],
|
||||||
|
group: 'commands',
|
||||||
|
memberName: 'reload',
|
||||||
|
description: 'Reloads a command or command group.',
|
||||||
|
details: oneLine`
|
||||||
|
The argument must be the name/ID (partial or whole) of a command or command group.
|
||||||
|
Providing a command group will reload all of the commands in that group.
|
||||||
|
Only the bot owner(s) may use this command.
|
||||||
|
`,
|
||||||
|
examples: ['reload some-command'],
|
||||||
|
ownerOnly: true,
|
||||||
|
guarded: true,
|
||||||
|
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
key: 'cmdOrGrp',
|
||||||
|
label: 'command/group',
|
||||||
|
prompt: 'Which command or group would you like to reload?',
|
||||||
|
type: 'group|command'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async run(msg, args) {
|
||||||
|
const { cmdOrGrp } = args;
|
||||||
|
const isCmd = Boolean(cmdOrGrp.groupID);
|
||||||
|
cmdOrGrp.reload();
|
||||||
|
|
||||||
|
if(this.client.shard) {
|
||||||
|
try {
|
||||||
|
await this.client.shard.broadcastEval(`
|
||||||
|
const ids = [${this.client.shard.ids.join(',')}];
|
||||||
|
if(!this.shard.ids.some(id => ids.includes(id))) {
|
||||||
|
this.registry.${isCmd ? 'commands' : 'groups'}.get('${isCmd ? cmdOrGrp.name : cmdOrGrp.id}').reload();
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
} catch(err) {
|
||||||
|
this.client.emit('warn', `Error when broadcasting command reload to other shards`);
|
||||||
|
this.client.emit('error', err);
|
||||||
|
if(isCmd) {
|
||||||
|
await msg.reply(`Reloaded \`${cmdOrGrp.name}\` command, but failed to reload on other shards.`);
|
||||||
|
} else {
|
||||||
|
await msg.reply(
|
||||||
|
`Reloaded all of the commands in the \`${cmdOrGrp.name}\` group, but failed to reload on other shards.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isCmd) {
|
||||||
|
await msg.reply(`Reloaded \`${cmdOrGrp.name}\` command${this.client.shard ? ' on all shards' : ''}.`);
|
||||||
|
} else {
|
||||||
|
await msg.reply(
|
||||||
|
`Reloaded all of the commands in the \`${cmdOrGrp.name}\` group${this.client.shard ? ' on all shards' : ''}.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
36
cmds/owner/unknown-command.js
Normal file
36
cmds/owner/unknown-command.js
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
const { trySend } = require('../../resources/functions');
|
||||||
|
const { chatAnswer } = require('../../resources/shaChat');
|
||||||
|
const Command = require('../../node_modules/@iceprod/discord.js-commando/src/commands/base');
|
||||||
|
|
||||||
|
module.exports = class UnknownCommandCommand extends Command {
|
||||||
|
constructor(client) {
|
||||||
|
super(client, {
|
||||||
|
name: 'unknown-command',
|
||||||
|
group: 'util',
|
||||||
|
memberName: 'unknown-command',
|
||||||
|
description: 'Displays help information for when an unknown command is used.',
|
||||||
|
examples: ['unknown-command kickeverybodyever'],
|
||||||
|
unknown: true,
|
||||||
|
hidden: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line
|
||||||
|
async run(msg) {
|
||||||
|
if (/^<@\!?\d{17,19}>\s.+/.test(msg.content)) {
|
||||||
|
const s = msg.cleanContent.slice((msg.guild ? msg.guild.member(msg.client.user).displayName.length : msg.client.user.username.length) + 2).trim();
|
||||||
|
return msg.channel.startTyping().then(trySend(msg.client, msg, await chatAnswer(s)).then(r => r)).catch(() => { }).finally(msg.channel.stopTyping());
|
||||||
|
}
|
||||||
|
if (!msg.guild && !msg.content.toLowerCase().startsWith(msg.client.commandPrefix)) return msg.channel.startTyping().then(trySend(msg.client, msg, await chatAnswer(msg.cleanContent)).then(r => r)).catch(() => { }).finally(msg.channel.stopTyping());
|
||||||
|
try {
|
||||||
|
return await msg.channel.send(
|
||||||
|
`Unknown command \`${msg.content}\`. Use ${msg.anyUsage(
|
||||||
|
'help',
|
||||||
|
msg.guild ? undefined : null,
|
||||||
|
msg.guild ? undefined : null
|
||||||
|
)} to view the command list.`
|
||||||
|
);
|
||||||
|
// eslint-disable-next-line
|
||||||
|
} catch (exception) { }
|
||||||
|
}
|
||||||
|
};
|
||||||
52
cmds/owner/unload.js
Normal file
52
cmds/owner/unload.js
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
const { oneLine } = require('common-tags');
|
||||||
|
const Command = require('../../node_modules/@iceprod/discord.js-commando/src/commands/base');
|
||||||
|
|
||||||
|
module.exports = class UnloadCommandCommand extends Command {
|
||||||
|
constructor(client) {
|
||||||
|
super(client, {
|
||||||
|
name: 'unload',
|
||||||
|
aliases: ['unload-command'],
|
||||||
|
group: 'commands',
|
||||||
|
memberName: 'unload',
|
||||||
|
description: 'Unloads a command.',
|
||||||
|
details: oneLine`
|
||||||
|
The argument must be the name/ID (partial or whole) of a command.
|
||||||
|
Only the bot owner(s) may use this command.
|
||||||
|
`,
|
||||||
|
examples: ['unload some-command'],
|
||||||
|
ownerOnly: true,
|
||||||
|
guarded: true,
|
||||||
|
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
key: 'command',
|
||||||
|
prompt: 'Which command would you like to unload?',
|
||||||
|
type: 'command'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async run(msg, args) {
|
||||||
|
args.command.unload();
|
||||||
|
|
||||||
|
if(this.client.shard) {
|
||||||
|
try {
|
||||||
|
await this.client.shard.broadcastEval(`
|
||||||
|
const ids = [${this.client.shard.ids.join(',')}];
|
||||||
|
if(!this.shard.ids.some(id => ids.includes(id))) {
|
||||||
|
this.registry.commands.get('${args.command.name}').unload();
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
} catch(err) {
|
||||||
|
this.client.emit('warn', `Error when broadcasting command unload to other shards`);
|
||||||
|
this.client.emit('error', err);
|
||||||
|
await msg.reply(`Unloaded \`${args.command.name}\` command, but failed to unload on other shards.`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await msg.reply(`Unloaded \`${args.command.name}\` command${this.client.shard ? ' on all shards' : ''}.`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -9,10 +9,11 @@ module.exports = class update extends commando.Command {
|
||||||
memberName: "update",
|
memberName: "update",
|
||||||
group: "owner",
|
group: "owner",
|
||||||
description: "Update Shasha.",
|
description: "Update Shasha.",
|
||||||
ownerOnly: true
|
ownerOnly: true,
|
||||||
|
guarded: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
run(msg) {
|
run(msg) {
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
105
cmds/utility/help.js
Normal file
105
cmds/utility/help.js
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
const { stripIndents, oneLine } = require('common-tags');
|
||||||
|
const Command = require('../../node_modules/@iceprod/discord.js-commando/src/commands/base');
|
||||||
|
const { disambiguation } = require('../../node_modules/@iceprod/discord.js-commando/src/util');
|
||||||
|
|
||||||
|
module.exports = class HelpCommand extends Command {
|
||||||
|
constructor(client) {
|
||||||
|
super(client, {
|
||||||
|
name: 'help',
|
||||||
|
group: 'util',
|
||||||
|
memberName: 'help',
|
||||||
|
aliases: ['commands'],
|
||||||
|
description: 'Displays a list of available commands, or detailed information for a specified command.',
|
||||||
|
details: oneLine`
|
||||||
|
The command may be part of a command name or a whole command name.
|
||||||
|
If it isn't specified, all available commands will be listed.
|
||||||
|
`,
|
||||||
|
examples: ['help', 'help prefix'],
|
||||||
|
guarded: true,
|
||||||
|
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
key: 'command',
|
||||||
|
prompt: 'Which command would you like to view the help for?',
|
||||||
|
type: 'string',
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async run(msg, args) { // eslint-disable-line complexity
|
||||||
|
const groups = this.client.registry.groups;
|
||||||
|
const commands = this.client.registry.findCommands(args.command, false, msg);
|
||||||
|
const showAll = args.command && args.command.toLowerCase() === 'all';
|
||||||
|
if (args.command && !showAll) {
|
||||||
|
if (commands.length === 1) {
|
||||||
|
let help = stripIndents`
|
||||||
|
${oneLine`
|
||||||
|
__Command **${commands[0].name}**:__ ${commands[0].description}
|
||||||
|
${commands[0].guildOnly ? ' (Usable only in servers)' : ''}
|
||||||
|
${commands[0].nsfw ? ' (NSFW)' : ''}
|
||||||
|
`}
|
||||||
|
|
||||||
|
**Format:** ${msg.anyUsage(`${commands[0].name}${commands[0].format ? ` ${commands[0].format}` : ''}`)}
|
||||||
|
`;
|
||||||
|
if (commands[0].aliases.length > 0) help += `\n**Aliases:** ${commands[0].aliases.join(', ')}`;
|
||||||
|
help += `\n${oneLine`
|
||||||
|
**Group:** ${commands[0].group.name}
|
||||||
|
(\`${commands[0].groupID}:${commands[0].memberName}\`)
|
||||||
|
`}`;
|
||||||
|
if (commands[0].details) help += `\n**Details:** ${commands[0].details}`;
|
||||||
|
if (commands[0].examples) help += `\n**Examples:**\n${commands[0].examples.join('\n')}`;
|
||||||
|
|
||||||
|
const messages = [];
|
||||||
|
try {
|
||||||
|
messages.push(await msg.direct(help));
|
||||||
|
if (msg.channel.type !== 'dm') messages.push(await msg.reply('Sent you a DM with information.'));
|
||||||
|
} catch (err) {
|
||||||
|
messages.push(await msg.reply('Unable to send you the help DM. You probably have DMs disabled.'));
|
||||||
|
}
|
||||||
|
return messages;
|
||||||
|
} else if (commands.length > 15) {
|
||||||
|
return msg.reply('Multiple commands found. Please be more specific.');
|
||||||
|
} else if (commands.length > 1) {
|
||||||
|
return msg.reply(disambiguation(commands, 'commands'));
|
||||||
|
} else {
|
||||||
|
return msg.reply(
|
||||||
|
`Unable to identify command. Use ${msg.usage(
|
||||||
|
null, msg.channel.type === 'dm' ? null : undefined, msg.channel.type === 'dm' ? null : undefined
|
||||||
|
)} to view the list of all commands.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const messages = [];
|
||||||
|
try {
|
||||||
|
messages.push(await msg.direct(stripIndents`
|
||||||
|
${oneLine`
|
||||||
|
To run a command in ${msg.guild ? msg.guild.name : 'any server'},
|
||||||
|
use ${Command.usage('command', msg.guild ? msg.guild.commandPrefix : null, this.client.user)}.
|
||||||
|
For example, ${Command.usage('prefix', msg.guild ? msg.guild.commandPrefix : null, this.client.user)}.
|
||||||
|
`}
|
||||||
|
To run a command in this DM, simply use ${Command.usage('command', null, null)} with no prefix.
|
||||||
|
|
||||||
|
Use ${this.usage('<command>', null, null)} to view detailed information about a specific command.
|
||||||
|
Use ${this.usage('all', null, null)} to view a list of *all* commands, not just available ones.
|
||||||
|
|
||||||
|
__**${showAll ? 'All commands' : `Available commands in ${msg.guild || 'this DM'}`}**__
|
||||||
|
|
||||||
|
${groups.filter(grp => grp.commands.some(cmd => !cmd.hidden && (showAll || cmd.isUsable(msg))))
|
||||||
|
.map(grp => stripIndents`
|
||||||
|
__${grp.name}__
|
||||||
|
${grp.commands.filter(cmd => !cmd.hidden && (showAll || cmd.isUsable(msg)))
|
||||||
|
.map(cmd => `**${cmd.name}:** ${cmd.description}${cmd.nsfw ? ' (NSFW)' : ''}`).join('\n')
|
||||||
|
}
|
||||||
|
`).join('\n\n')
|
||||||
|
}
|
||||||
|
`, { split: true }));
|
||||||
|
if (msg.channel.type !== 'dm') messages.push(await msg.reply('Sent you a DM with information.'));
|
||||||
|
} catch (err) {
|
||||||
|
messages.push(await msg.reply('Unable to send you the help DM. You probably have DMs disabled.'));
|
||||||
|
}
|
||||||
|
return messages;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
28
cmds/utility/ping.js
Normal file
28
cmds/utility/ping.js
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
const { oneLine } = require('common-tags');
|
||||||
|
const Command = require('../../node_modules/@iceprod/discord.js-commando/src/commands/base');
|
||||||
|
|
||||||
|
module.exports = class PingCommand extends Command {
|
||||||
|
constructor(client) {
|
||||||
|
super(client, {
|
||||||
|
name: 'ping',
|
||||||
|
group: 'util',
|
||||||
|
memberName: 'ping',
|
||||||
|
description: 'Checks the bot\'s ping to the Discord server.',
|
||||||
|
throttling: {
|
||||||
|
usages: 5,
|
||||||
|
duration: 10
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async run(msg) {
|
||||||
|
const pingMsg = await msg.reply('Pinging...');
|
||||||
|
return pingMsg.edit(oneLine`
|
||||||
|
${msg.channel.type !== 'dm' ? `${msg.author},` : ''}
|
||||||
|
Pong! The message round-trip took ${
|
||||||
|
(pingMsg.editedTimestamp || pingMsg.createdTimestamp) - (msg.editedTimestamp || msg.createdTimestamp)
|
||||||
|
}ms.
|
||||||
|
${this.client.ws.ping ? `The heartbeat ping is ${Math.round(this.client.ws.ping)}ms.` : ''}
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
};
|
||||||
67
cmds/utility/prefix.js
Normal file
67
cmds/utility/prefix.js
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
const { stripIndents, oneLine } = require('common-tags');
|
||||||
|
const Command = require('../../node_modules/@iceprod/discord.js-commando/src/commands/base');
|
||||||
|
|
||||||
|
module.exports = class PrefixCommand extends Command {
|
||||||
|
constructor(client) {
|
||||||
|
super(client, {
|
||||||
|
name: 'prefix',
|
||||||
|
group: 'util',
|
||||||
|
memberName: 'prefix',
|
||||||
|
description: 'Shows or sets the command prefix.',
|
||||||
|
format: '[prefix/"default"/"none"]',
|
||||||
|
details: oneLine`
|
||||||
|
If no prefix is provided, the current prefix will be shown.
|
||||||
|
If the prefix is "default", the prefix will be reset to the bot's default prefix.
|
||||||
|
If the prefix is "none", the prefix will be removed entirely, only allowing mentions to run commands.
|
||||||
|
Only administrators may change the prefix.
|
||||||
|
`,
|
||||||
|
examples: ['prefix', 'prefix -', 'prefix omg!', 'prefix default', 'prefix none'],
|
||||||
|
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
key: 'prefix',
|
||||||
|
prompt: 'What would you like to set the bot\'s prefix to?',
|
||||||
|
type: 'string',
|
||||||
|
max: 15,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async run(msg, args) {
|
||||||
|
// Just output the prefix
|
||||||
|
if(!args.prefix) {
|
||||||
|
const prefix = msg.guild ? msg.guild.commandPrefix : this.client.commandPrefix;
|
||||||
|
return msg.reply(stripIndents`
|
||||||
|
${prefix ? `The command prefix is \`${prefix}\`.` : 'There is no command prefix.'}
|
||||||
|
To run commands, use ${msg.anyUsage('command')}.
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the user's permission before changing anything
|
||||||
|
if(msg.guild) {
|
||||||
|
if(!msg.member.permissions.has('ADMINISTRATOR') && !this.client.isOwner(msg.author)) {
|
||||||
|
return msg.reply('Only administrators may change the command prefix.');
|
||||||
|
}
|
||||||
|
} else if(!this.client.isOwner(msg.author)) {
|
||||||
|
return msg.reply('Only the bot owner(s) may change the global command prefix.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the prefix
|
||||||
|
const lowercase = args.prefix.toLowerCase();
|
||||||
|
const prefix = lowercase === 'none' ? '' : args.prefix;
|
||||||
|
let response;
|
||||||
|
if(lowercase === 'default') {
|
||||||
|
if(msg.guild) msg.guild.commandPrefix = null; else this.client.commandPrefix = null;
|
||||||
|
const current = this.client.commandPrefix ? `\`${this.client.commandPrefix}\`` : 'no prefix';
|
||||||
|
response = `Reset the command prefix to the default (currently ${current}).`;
|
||||||
|
} else {
|
||||||
|
if(msg.guild) msg.guild.commandPrefix = prefix; else this.client.commandPrefix = prefix;
|
||||||
|
response = prefix ? `Set the command prefix to \`${args.prefix}\`.` : 'Removed the command prefix entirely.';
|
||||||
|
}
|
||||||
|
|
||||||
|
await msg.reply(`${response} To run commands, use ${msg.anyUsage('command')}.`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
Loading…
Reference in a new issue