diff options
Diffstat (limited to 'src/commands/dev')
-rw-r--r-- | src/commands/dev/eval.ts | 101 | ||||
-rw-r--r-- | src/commands/dev/reload.ts | 69 | ||||
-rw-r--r-- | src/commands/dev/setLevel.ts | 81 |
3 files changed, 251 insertions, 0 deletions
diff --git a/src/commands/dev/eval.ts b/src/commands/dev/eval.ts new file mode 100644 index 0000000..cfe75cc --- /dev/null +++ b/src/commands/dev/eval.ts @@ -0,0 +1,101 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { BushCommand } from '../../lib/extensions/BushCommand'; +import { MessageEmbed, Message } from 'discord.js'; +import { inspect, promisify } from 'util'; +import { exec } from 'child_process'; + +const clean = (text) => { + if (typeof text === 'string') return text.replace(/`/g, '`' + String.fromCharCode(8203)).replace(/@/g, '@' + String.fromCharCode(8203)); + else return text; +}; + +export default class EvalCommand extends BushCommand { + public constructor() { + super('eval', { + aliases: ['eval', 'ev'], + category: 'dev', + description: { + content: 'Use the command to eval stuff in the bot.', + usage: 'eval <code> [--silent] [--depth #]', + examples: ['eval message.guild.name', 'eval this.client.ownerID'] + }, + args: [ + { + id: 'depth', + match: 'option', + type: 'number', + flag: '--depth', + default: 0 + }, + { + id: 'silent', + match: 'flag', + flag: '--silent' + }, + { + id: 'code', + match: 'rest', + type: 'string', + prompt: { + start: 'What would you like to eval?', + retry: 'Invalid code to eval. What would you like to eval?' + } + } + ], + ownerOnly: true, + clientPermissions: ['EMBED_LINKS'] + }); + } + + public async exec(message: Message, { depth, code, silent }: { depth: number; code: string; silent: boolean }): Promise<void> { + const embed: MessageEmbed = new MessageEmbed(); + + try { + let output; + const me = message.member, + member = message.member, + bot = this.client, + guild = message.guild, + channel = message.channel, + config = this.client.config, + sh = promisify(exec), + models = this.client.db.models, + got = require('got'); // eslint-disable-line @typescript-eslint/no-var-requires + output = eval(code); + output = await output; + if (typeof output !== 'string') output = inspect(output, { depth }); + output = output.replace(new RegExp(this.client.token, 'g'), '[token omitted]'); + output = clean(output); + embed + .setTitle('✅ Evaled code successfully') + .addField('📥 Input', code.length > 1012 ? 'Too large to display. Hastebin: ' + (await this.client.util.haste(code)) : '```js\n' + code + '```') + .addField('📤 Output', output.length > 1012 ? 'Too large to display. Hastebin: ' + (await this.client.util.haste(output)) : '```js\n' + output + '```') + .setColor('#66FF00') + .setFooter(message.author.username, message.author.displayAvatarURL({ dynamic: true })) + .setTimestamp(); + } catch (e) { + embed + .setTitle('❌ Code was not able to be evaled') + .addField('📥 Input', code.length > 1012 ? 'Too large to display. Hastebin: ' + (await this.client.util.haste(code)) : '```js\n' + code + '```') + .addField( + '📤 Output', + e.length > 1012 + ? 'Too large to display. Hastebin: ' + (await this.client.util.haste(e)) + : '```js\n' + e + '```Full stack:' + (await this.client.util.haste(e.stack)) + ) + .setColor('#FF0000') + .setFooter(message.author.username, message.author.displayAvatarURL({ dynamic: true })) + .setTimestamp(); + } + if (!silent) { + await message.util.send(embed); + } else { + try { + await message.author.send(embed); + await message.react('<a:Check_Mark:790373952760971294>'); + } catch (e) { + await message.react('❌'); + } + } + } +} diff --git a/src/commands/dev/reload.ts b/src/commands/dev/reload.ts new file mode 100644 index 0000000..36c6fd7 --- /dev/null +++ b/src/commands/dev/reload.ts @@ -0,0 +1,69 @@ +import { BushCommand } from '../../lib/extensions/BushCommand'; +import { stripIndent } from 'common-tags'; +import { Message } from 'discord.js'; +import { CommandInteraction } from 'discord.js'; +import { SlashCommandOption } from '../../lib/extensions/Util'; +import { ApplicationCommandOptionType } from 'discord-api-types'; + +export default class ReloadCommand extends BushCommand { + constructor() { + super('reload', { + aliases: ['reload'], + category: 'dev', + description: { + content: 'Reloads the bot', + usage: 'reload', + examples: ['reload'] + }, + args: [ + { + id: 'fast', + match: 'flag', + flag: '--fast' + } + ], + ownerOnly: true, + typing: true, + slashCommandOptions: [ + { + type: ApplicationCommandOptionType.BOOLEAN, + name: 'fast', + description: 'Wheather to use esbuild for fast compiling or not', + required: false + } + ] + }); + } + + private async getResponse(fast: boolean): Promise<string> { + try { + const s = new Date(); + await this.client.util.shell(`yarn build-${fast ? 'esbuild' : 'tsc'}`); + this.client.commandHandler.reloadAll(); + this.client.listenerHandler.reloadAll(); + this.client.inhibitorHandler.reloadAll(); + return `🔁 Successfully reloaded! (${ + new Date().getTime() - s.getTime() + }ms)`; + } catch (e) { + return stripIndent` + An error occured while reloading: + ${await this.client.util.haste(e.stack)} + `; + } + } + + public async exec( + message: Message, + { fast }: { fast: boolean } + ): Promise<void> { + await message.util.send(await this.getResponse(fast)); + } + + public async execSlash( + message: CommandInteraction, + { fast }: { fast: SlashCommandOption<boolean> } + ): Promise<void> { + await message.reply(await this.getResponse(fast?.value)); + } +} diff --git a/src/commands/dev/setLevel.ts b/src/commands/dev/setLevel.ts new file mode 100644 index 0000000..3a1bc85 --- /dev/null +++ b/src/commands/dev/setLevel.ts @@ -0,0 +1,81 @@ +import { ApplicationCommandOptionType } from 'discord-api-types'; +import { CommandInteraction } from 'discord.js'; +import { User } from 'discord.js'; +import { Message } from 'discord.js'; +import { BushCommand } from '../../lib/extensions/BushCommand'; +import { SlashCommandOption } from '../../lib/extensions/Util'; +import { Level } from '../../lib/models'; +import AllowedMentions from '../../lib/utils/AllowedMentions'; + +export default class SetLevelCommand extends BushCommand { + constructor() { + super('setlevel', { + aliases: ['setlevel'], + category: 'dev', + description: { + content: 'Sets the level of a user', + usage: 'setlevel <user> <level>', + examples: ['setlevel @Moulberry 69'] //nice + }, + args: [ + { + id: 'user', + type: 'user', + prompt: { + start: 'What user would you like to change the level of?', + retry: 'Invalid user. What user would you like to change the level of?' + } + }, + { + id: 'level', + type: 'number', + prompt: { + start: 'What level would you like to set?', + retry: 'Invalid user. What level would you like to set?' + } + } + ], + ownerOnly: true, + slashCommandOptions: [ + { + type: ApplicationCommandOptionType.USER, + name: 'user', + description: 'The user to change the level of', + required: true + }, + { + type: ApplicationCommandOptionType.INTEGER, + name: 'level', + description: 'The level to set the user to', + required: true + } + ] + }); + } + + private async setLevel(user: User, level: number): Promise<string> { + const [levelEntry] = await Level.findOrBuild({ + where: { + id: user.id + }, + defaults: { + id: user.id + } + }); + levelEntry.xp = Level.convertLevelToXp(level); + await levelEntry.save(); + return `Successfully set level of <@${user.id}> to \`${level}\` (\`${levelEntry.xp}\` XP)`; + } + + async exec(message: Message, { user, level }: { user: User; level: number }): Promise<void> { + await message.util.send(await this.setLevel(user, level), { + allowedMentions: AllowedMentions.none() + }); + } + + async execSlash(message: CommandInteraction, { user, level }: { user: SlashCommandOption<void>; level: SlashCommandOption<number> }): Promise<void> { + await message.reply(await this.setLevel(user.user, level.value), { + allowedMentions: AllowedMentions.none() + }); + } +} |