diff --git a/bot/src/bot/commands/ban.ts b/bot/src/bot/commands/ban.ts index 0cc4914..d435625 100644 --- a/bot/src/bot/commands/ban.ts +++ b/bot/src/bot/commands/ban.ts @@ -2,7 +2,7 @@ import { ulid } from "ulid"; import { client } from "../../index"; import Infraction from "../../struct/antispam/Infraction"; import InfractionType from "../../struct/antispam/InfractionType"; -import Command from "../../struct/Command"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import MessageCommandContext from "../../struct/MessageCommandContext"; import TempBan from "../../struct/TempBan"; import { fetchUsername, logModAction } from "../modules/mod_logs"; @@ -10,6 +10,7 @@ import { storeTempBan } from "../modules/tempbans"; import { isModerator, NO_MANAGER_MSG, parseUserOrId, storeInfraction } from "../util"; import Day from 'dayjs'; import RelativeTime from 'dayjs/plugin/relativeTime'; +import CommandCategory from "../../struct/commands/CommandCategory"; Day.extend(RelativeTime); @@ -19,7 +20,7 @@ export default { description: 'Ban a member from the server', syntax: '/ban @username [10m|1h|...?] [reason?]', removeEmptyArgs: true, - category: 'moderation', + category: CommandCategory.Moderation, run: async (message: MessageCommandContext, args: string[]) => { if (!await isModerator(message)) return message.reply(NO_MANAGER_MSG); @@ -123,4 +124,4 @@ export default { ]); } } -} as Command; +} as SimpleCommand; diff --git a/bot/src/bot/commands/bot_managers.ts b/bot/src/bot/commands/bot_managers.ts index c1d4e05..d50888c 100644 --- a/bot/src/bot/commands/bot_managers.ts +++ b/bot/src/bot/commands/bot_managers.ts @@ -1,9 +1,10 @@ -import Command from "../../struct/Command"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import { hasPerm, parseUser } from "../util"; import ServerConfig from "../../struct/ServerConfig"; import { client } from "../.."; import { User } from "@janderedev/revolt.js/dist/maps/Users"; import MessageCommandContext from "../../struct/MessageCommandContext"; +import CommandCategory from "../../struct/commands/CommandCategory"; const SYNTAX = '/admin add @user; /admin remove @user; /admin list'; @@ -12,7 +13,7 @@ export default { aliases: [ 'admins', 'manager', 'managers' ], description: 'Allow users to control the bot\'s configuration', syntax: SYNTAX, - category: 'configuration', + category: CommandCategory.Config, run: async (message: MessageCommandContext, args: string[]) => { if (!hasPerm(message.member!, 'ManageServer')) return message.reply('You need **ManageServer** permission to use this command.'); @@ -63,4 +64,4 @@ export default { message.reply(`Available subcommands: ${SYNTAX}`); } } -} as Command; +} as SimpleCommand; diff --git a/bot/src/bot/commands/botadm.ts b/bot/src/bot/commands/botadm.ts index e405631..67e37f7 100644 --- a/bot/src/bot/commands/botadm.ts +++ b/bot/src/bot/commands/botadm.ts @@ -1,4 +1,4 @@ -import Command from "../../struct/Command"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import MessageCommandContext from "../../struct/MessageCommandContext"; import { client } from "../.."; import { commands, DEFAULT_PREFIX, ownerIDs } from "../modules/command_handler"; @@ -8,6 +8,7 @@ import path from 'path'; import { wordlist } from "../modules/user_scan"; import { User } from "@janderedev/revolt.js/dist/maps/Users"; import { adminBotLog } from "../logging"; +import CommandCategory from "../../struct/commands/CommandCategory"; // id: expireDate const sudoOverrides: { [key: string]: number|null } = {} @@ -37,7 +38,7 @@ export default { description: 'Bot administration', removeEmptyArgs: true, restrict: 'BOTOWNER', - category: 'owner', + category: CommandCategory.Owner, run: async (message: MessageCommandContext, args: string[]) => { if (!args.length) return message.reply('No subcommand specified. Available subcommands: ' + SUBCOMMANDS.join(', ')); @@ -130,6 +131,6 @@ export default { } } catch(e) { console.error(e) } } -} as Command; +} as SimpleCommand; export { isSudo, updateSudoTimeout } diff --git a/bot/src/bot/commands/botctl.ts b/bot/src/bot/commands/botctl.ts index 696478a..69e1cb4 100644 --- a/bot/src/bot/commands/botctl.ts +++ b/bot/src/bot/commands/botctl.ts @@ -1,6 +1,7 @@ import { FindOneResult } from "monk"; import { client } from "../.."; -import Command from "../../struct/Command"; +import CommandCategory from "../../struct/commands/CommandCategory"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import MessageCommandContext from "../../struct/MessageCommandContext"; import ServerConfig from "../../struct/ServerConfig"; import { scanServer } from "../modules/user_scan"; @@ -12,7 +13,7 @@ export default { name: 'botctl', aliases: null, description: 'Perform administrative actions', - category: 'configuration', + category: CommandCategory.Config, run: async (message: MessageCommandContext, args: string[]) => { if (!isBotManager(message)) return message.reply(NO_MANAGER_MSG); @@ -55,4 +56,4 @@ export default { message.reply(`Unknown option`); } } -} as Command; +} as SimpleCommand; diff --git a/bot/src/bot/commands/debug.ts b/bot/src/bot/commands/debug.ts index ea3e784..80b981d 100644 --- a/bot/src/bot/commands/debug.ts +++ b/bot/src/bot/commands/debug.ts @@ -1,11 +1,12 @@ -import Command from "../../struct/Command"; +import CommandCategory from "../../struct/commands/CommandCategory"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import MessageCommandContext from "../../struct/MessageCommandContext"; export default { name: 'debug', aliases: null, description: 'Gives info helpful for development and debugging', - category: 'misc', + category: CommandCategory.Misc, run: (message: MessageCommandContext, args: string[]) => { message.reply(`Server ID: ${message.channel?.server_id || 'None'}\n` + `Server context: ${message.serverContext._id} ` @@ -13,4 +14,4 @@ export default { + `Channel ID: ${message.channel_id}\n` + `User ID: ${message.author_id}`); } -} as Command; +} as SimpleCommand; diff --git a/bot/src/bot/commands/eval.ts b/bot/src/bot/commands/eval.ts index 4eba7b3..bf6ca76 100644 --- a/bot/src/bot/commands/eval.ts +++ b/bot/src/bot/commands/eval.ts @@ -1,8 +1,9 @@ -import Command from "../../struct/Command"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import { Message } from "@janderedev/revolt.js/dist/maps/Messages"; import { inspect } from 'util'; import { client } from "../.."; import MessageCommandContext from "../../struct/MessageCommandContext"; +import CommandCategory from "../../struct/commands/CommandCategory"; export default { name: 'eval', @@ -10,7 +11,7 @@ export default { description: 'Evaluate JS code', restrict: 'BOTOWNER', removeEmptyArgs: false, - category: 'owner', + category: CommandCategory.Owner, run: async (message: MessageCommandContext, args: string[]) => { let cmd = args.join(' '); @@ -38,7 +39,7 @@ export default { m?.edit({ content: `## Execution failed\n\`\`\`js\n${render(e)}\n\`\`\`` }); } } -} as Command; +} as SimpleCommand; function removeSecrets(input: string): string { if (process.env['DB_PASS']) input = input.replace(new RegExp(process.env['DB_PASS']!, 'gi'), '[Secret redacted]'); diff --git a/bot/src/bot/commands/help.ts b/bot/src/bot/commands/help.ts index 757970f..1925e0f 100644 --- a/bot/src/bot/commands/help.ts +++ b/bot/src/bot/commands/help.ts @@ -1,30 +1,34 @@ -import Command from "../../struct/Command"; +import Command from "../../struct/commands/SimpleCommand"; import { commands, DEFAULT_PREFIX, ownerIDs } from "../modules/command_handler"; -import CommandCategory from "../../struct/CommandCategory"; import MessageCommandContext from "../../struct/MessageCommandContext"; +import CommandCategory from "../../struct/commands/CommandCategory"; -const categories: { [key: string]: CommandCategory } = { - 'moderation': { +const categories: { [key in CommandCategory]: { + friendlyName: string, + description: string, + aliases: string[], +} } = { + [CommandCategory.Moderation]: { friendlyName: 'Moderation', description: 'Moderation-focused commands', aliases: [ 'mod', 'mods' ], }, - 'configuration': { + [CommandCategory.Config]: { friendlyName: 'Configuration', description: 'Configure AutoMod', aliases: [ 'conf', 'config' ], }, - 'misc': { + [CommandCategory.Misc]: { friendlyName: 'Misc', description: 'Random stuff :yed:', aliases: [ 'miscellaneous', 'weirdwordicantspell' ], }, - 'owner': { + [CommandCategory.Owner]: { friendlyName: 'Owner', description: 'Owner-only commands for managing AutoMod', aliases: [], }, - 'uncategorized': { + [CommandCategory.None]: { friendlyName: 'Uncategorized', description: 'Uncategorized commands', aliases: [], @@ -36,7 +40,7 @@ export default { aliases: null, description: 'Help command.', removeEmptyArgs: true, - category: 'misc', + category: CommandCategory.Misc, run: async (message: MessageCommandContext, args: string[]) => { const isBotOwner = ownerIDs.includes(message.author_id); const prefix = DEFAULT_PREFIX; // TODO: fetch prefix from server config @@ -50,15 +54,15 @@ export default { let total = 0; - for (const categoryName in categories) { + for (const categoryName in CommandCategory) { let cmdCount = commands.filter( - cmd => ((cmd.category || 'uncategorized') == categoryName) && + cmd => (cmd.category == categoryName) && (cmd.restrict == 'BOTOWNER' ? isBotOwner : true) // Ensure owner commands are only shown to bot owner ).length; if (cmdCount > 0) { total++; - const category = categories[categoryName]; + const category = (categories as any)[categoryName]; msg += `**${category.friendlyName}**\n` + ` \u200b \u200b ↳ ${(category.description)} \u200b $\\big |$ \u200b **${cmdCount}** command${cmdCount == 1 ? '' : 's'}\n`; } diff --git a/bot/src/bot/commands/kick.ts b/bot/src/bot/commands/kick.ts index fd6f42d..a7785ed 100644 --- a/bot/src/bot/commands/kick.ts +++ b/bot/src/bot/commands/kick.ts @@ -3,7 +3,8 @@ import { ulid } from "ulid"; import { client } from "../.."; import Infraction from "../../struct/antispam/Infraction"; import InfractionType from "../../struct/antispam/InfractionType"; -import Command from "../../struct/Command"; +import CommandCategory from "../../struct/commands/CommandCategory"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import MessageCommandContext from "../../struct/MessageCommandContext"; import { logModAction } from "../modules/mod_logs"; import { isModerator, NO_MANAGER_MSG, parseUser, storeInfraction } from "../util"; @@ -14,7 +15,7 @@ export default { description: 'Eject a member from the server', syntax: '/kick @username [reason?]', removeEmptyArgs: true, - category: 'moderation', + category: CommandCategory.Moderation, run: async (message: MessageCommandContext, args: string[]) => { if (!await isModerator(message)) return message.reply(NO_MANAGER_MSG); @@ -67,4 +68,4 @@ export default { logModAction('kick', message.serverContext, message.member!, targetUser._id, reason, infraction._id), ]); } -} as Command; +} as SimpleCommand; diff --git a/bot/src/bot/commands/login.ts b/bot/src/bot/commands/login.ts index f49094a..8f7dc95 100644 --- a/bot/src/bot/commands/login.ts +++ b/bot/src/bot/commands/login.ts @@ -1,6 +1,7 @@ import { FindOneResult } from "monk"; import { client } from "../.."; -import Command from "../../struct/Command"; +import CommandCategory from "../../struct/commands/CommandCategory"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import MessageCommandContext from "../../struct/MessageCommandContext"; import PendingLogin from "../../struct/PendingLogin"; import logger from "../logger"; @@ -10,7 +11,7 @@ export default { name: 'login', aliases: null, description: 'Log into the web dashboard', - category: 'misc', + category: CommandCategory.Misc, run: async (message: MessageCommandContext, args: string[]) => { try { const code = args.shift(); @@ -59,4 +60,4 @@ export default { message.reply(`An error occurred: ${e}`); } } -} as Command; +} as SimpleCommand; diff --git a/bot/src/bot/commands/logout.ts b/bot/src/bot/commands/logout.ts index 9b13490..6d93f60 100644 --- a/bot/src/bot/commands/logout.ts +++ b/bot/src/bot/commands/logout.ts @@ -1,6 +1,7 @@ import { FindOneResult, FindResult } from "monk"; import { client } from "../.."; -import Command from "../../struct/Command"; +import CommandCategory from "../../struct/commands/CommandCategory"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import MessageCommandContext from "../../struct/MessageCommandContext"; import PendingLogin from "../../struct/PendingLogin"; import { DEFAULT_PREFIX } from "../modules/command_handler"; @@ -9,7 +10,7 @@ export default { name: 'logout', aliases: null, description: 'Log out of sessions created with /login', - category: 'misc', + category: CommandCategory.Misc, run: async (message: MessageCommandContext, args: string[]) => { try { const code = args.shift(); @@ -56,4 +57,4 @@ export default { message.reply(`An error occurred: ${e}`); } } -} as Command; +} as SimpleCommand; diff --git a/bot/src/bot/commands/moderator.ts b/bot/src/bot/commands/moderator.ts index b7158ce..880d60d 100644 --- a/bot/src/bot/commands/moderator.ts +++ b/bot/src/bot/commands/moderator.ts @@ -1,10 +1,11 @@ -import Command from "../../struct/Command"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import { Message } from "@janderedev/revolt.js/dist/maps/Messages"; import { isBotManager, NO_MANAGER_MSG, parseUser } from "../util"; import ServerConfig from "../../struct/ServerConfig"; import { client } from "../.."; import { User } from "@janderedev/revolt.js/dist/maps/Users"; import MessageCommandContext from "../../struct/MessageCommandContext"; +import CommandCategory from "../../struct/commands/CommandCategory"; const SYNTAX = '/mod add @user; /mod remove @user; /mod list'; @@ -15,7 +16,7 @@ export default { aliases: [ 'moderators', 'mod', 'mods' ], description: 'Allow users to moderate other users', syntax: SYNTAX, - category: 'configuration', + category: CommandCategory.Config, run: async (message: MessageCommandContext, args: string[]) => { if (!await isBotManager(message)) return message.reply(NO_MANAGER_MSG); @@ -65,4 +66,4 @@ export default { message.reply(`Available subcommands: ${SYNTAX}`); } } -} as Command; +} as SimpleCommand; diff --git a/bot/src/bot/commands/ping.ts b/bot/src/bot/commands/ping.ts index 5f3031a..b0a2715 100644 --- a/bot/src/bot/commands/ping.ts +++ b/bot/src/bot/commands/ping.ts @@ -1,13 +1,14 @@ -import Command from "../../struct/Command"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import { Message } from "@janderedev/revolt.js/dist/maps/Messages"; import { client } from "../.."; import MessageCommandContext from "../../struct/MessageCommandContext"; +import CommandCategory from "../../struct/commands/CommandCategory"; export default { name: 'ping', aliases: null, description: 'ping pong', - category: 'misc', + category: CommandCategory.Misc, run: async (message: MessageCommandContext, args: string[]) => { let now = Date.now(); message.reply(`Measuring...`) @@ -18,4 +19,4 @@ export default { + `Msg: \`${Math.round(Date.now() - now) / 2}ms\`` }); }); } -} as Command; +} as SimpleCommand; diff --git a/bot/src/bot/commands/prefix.ts b/bot/src/bot/commands/prefix.ts index d45d736..ec81111 100644 --- a/bot/src/bot/commands/prefix.ts +++ b/bot/src/bot/commands/prefix.ts @@ -1,10 +1,11 @@ -import Command from "../../struct/Command"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import { Message } from "@janderedev/revolt.js/dist/maps/Messages"; import { client } from "../.."; import ServerConfig from "../../struct/ServerConfig"; import { DEFAULT_PREFIX } from "../modules/command_handler"; import { hasPerm, isBotManager, NO_MANAGER_MSG } from "../util"; import MessageCommandContext from "../../struct/MessageCommandContext"; +import CommandCategory from "../../struct/commands/CommandCategory"; const SYNTAX = '/prefix set [new prefix]; /prefix get; prefix clear'; const MENTION_TEXT = 'You can also @mention me instead of using the prefix.'; @@ -14,7 +15,7 @@ export default { aliases: null, description: 'Configure AutoMod\'s prefix', syntax: SYNTAX, - category: 'configuration', + category: CommandCategory.Config, run: async (message: MessageCommandContext, args: string[]) => { let config: ServerConfig = (await client.db.get('servers').findOne({ id: message.channel?.server_id })) ?? {}; @@ -56,7 +57,7 @@ export default { } } -} as Command; +} as SimpleCommand; function validatePrefix(prefix: string): string|true { // Check length diff --git a/bot/src/bot/commands/purge.ts b/bot/src/bot/commands/purge.ts index bcd4c61..07de003 100644 --- a/bot/src/bot/commands/purge.ts +++ b/bot/src/bot/commands/purge.ts @@ -1,8 +1,9 @@ -import Command from "../../struct/Command"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import { Message } from "@janderedev/revolt.js/dist/maps/Messages"; import { decodeTime } from 'ulid'; import { isModerator, parseUser } from "../util"; import MessageCommandContext from "../../struct/MessageCommandContext"; +import CommandCategory from "../../struct/commands/CommandCategory"; const SYNTAX = '/purge [SELECTOR] [@user?[, @user?[, ...]]]; where SELECTOR: [number] || [messageID]-[messageID]'; const MAX_PURGE_AMOUNT = 100; @@ -12,7 +13,7 @@ export default { aliases: [ 'clear' ], description: 'Mass delete messages', syntax: SYNTAX, - category: 'moderation', + category: CommandCategory.Moderation, run: async (message: MessageCommandContext, args: string[]) => { try { if (!message.member || !await isModerator(message)) return message.reply('🔒 Access denied'); @@ -89,4 +90,4 @@ export default { message.channel?.sendMessage(`An error has occurred: ${e}`); } } -} as Command; +} as SimpleCommand; diff --git a/bot/src/bot/commands/settings.ts b/bot/src/bot/commands/settings.ts index 44732c3..4d0af53 100644 --- a/bot/src/bot/commands/settings.ts +++ b/bot/src/bot/commands/settings.ts @@ -1,13 +1,14 @@ -import Command from "../../struct/Command"; +import CommandCategory from "../../struct/commands/CommandCategory"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import MessageCommandContext from "../../struct/MessageCommandContext"; export default { name: 'settings', aliases: [ 'setting' ], description: 'Manage AutoMod\'s configuration', - category: 'configuration', + category: CommandCategory.Config, run: async (message: MessageCommandContext, args: string[]) => { await message.reply(`Bot configuration can be managed from ` + `[here](<${process.env.WEB_UI_URL || 'https://automod.janderedev.xyz'}/dashboard>).`); } -} as Command; +} as SimpleCommand; diff --git a/bot/src/bot/commands/shell_eval.ts b/bot/src/bot/commands/shell_eval.ts index d46b3d9..7efb4ef 100644 --- a/bot/src/bot/commands/shell_eval.ts +++ b/bot/src/bot/commands/shell_eval.ts @@ -1,7 +1,8 @@ -import Command from "../../struct/Command"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import { Message } from "@janderedev/revolt.js/dist/maps/Messages"; import { exec } from 'child_process'; import MessageCommandContext from "../../struct/MessageCommandContext"; +import CommandCategory from "../../struct/commands/CommandCategory"; export default { name: 'shell', @@ -9,7 +10,7 @@ export default { description: 'Run code in a shell', restrict: 'BOTOWNER', removeEmptyArgs: false, - category: 'owner', + category: CommandCategory.Owner, run: async (message: MessageCommandContext, args: string[]) => { let cmd = args.join(' '); @@ -44,4 +45,4 @@ export default { message.channel?.sendMessage(`${e}`); } } -} as Command; +} as SimpleCommand; diff --git a/bot/src/bot/commands/test.ts b/bot/src/bot/commands/test.ts index 3e02406..15b70a2 100644 --- a/bot/src/bot/commands/test.ts +++ b/bot/src/bot/commands/test.ts @@ -1,12 +1,13 @@ -import Command from "../../struct/Command"; +import CommandCategory from "../../struct/commands/CommandCategory"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import MessageCommandContext from "../../struct/MessageCommandContext"; export default { name: 'test', aliases: [ 'testalias' ], description: 'Test command', - category: 'misc', + category: CommandCategory.Misc, run: (message: MessageCommandContext, args: string[]) => { message.reply('Beep boop.'); } -} as Command; +} as SimpleCommand; diff --git a/bot/src/bot/commands/unban.ts b/bot/src/bot/commands/unban.ts index a4aabfc..e9882f7 100644 --- a/bot/src/bot/commands/unban.ts +++ b/bot/src/bot/commands/unban.ts @@ -1,6 +1,7 @@ import { FindResult } from "monk"; import { client } from "../.."; -import Command from "../../struct/Command"; +import CommandCategory from "../../struct/commands/CommandCategory"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import MessageCommandContext from "../../struct/MessageCommandContext"; import TempBan from "../../struct/TempBan"; import { removeTempBan } from "../modules/tempbans"; @@ -11,7 +12,7 @@ export default { aliases: [ 'pardon' ], description: 'Unbans a user', syntax: '/unban [@user or ID]', - category: 'moderation', + category: CommandCategory.Moderation, run: async (message: MessageCommandContext, args: string[]) => { if (!await isModerator(message)) return message.reply(NO_MANAGER_MSG); @@ -74,4 +75,4 @@ export default { await msg.edit({ content: `@${bannedUser.username} has been unbanned.` }); } catch(e) { console.error(e) } } -} as Command; +} as SimpleCommand; diff --git a/bot/src/bot/commands/votekick.ts b/bot/src/bot/commands/votekick.ts index cc7c0a5..1d9d969 100644 --- a/bot/src/bot/commands/votekick.ts +++ b/bot/src/bot/commands/votekick.ts @@ -1,7 +1,8 @@ import { FindResult } from "monk"; import { ulid } from "ulid"; import { client } from "../.."; -import Command from "../../struct/Command"; +import CommandCategory from "../../struct/commands/CommandCategory"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import MessageCommandContext from "../../struct/MessageCommandContext"; import ServerConfig from "../../struct/ServerConfig"; import { logModAction } from "../modules/mod_logs"; @@ -21,7 +22,7 @@ export default { name: 'votekick', aliases: [ 'voteban' ], description: 'Allow trusted users to vote kick users', - category: 'moderation', + category: CommandCategory.Moderation, run: async (message: MessageCommandContext, args: string[]) => { try { const serverConfig: ServerConfig = await client.db.get('servers').findOne({ id: message.serverContext._id }); @@ -113,4 +114,4 @@ export default { message.reply('Oops, something happened: ' + e); } } -} as Command; +} as SimpleCommand; diff --git a/bot/src/bot/commands/warn.ts b/bot/src/bot/commands/warn.ts index 7c5eaad..baf2479 100644 --- a/bot/src/bot/commands/warn.ts +++ b/bot/src/bot/commands/warn.ts @@ -1,17 +1,18 @@ -import Command from "../../struct/Command"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import { isModerator, NO_MANAGER_MSG, parseUserOrId, storeInfraction } from "../util"; import Infraction from "../../struct/antispam/Infraction"; import { ulid } from "ulid"; import InfractionType from "../../struct/antispam/InfractionType"; import { fetchUsername, logModAction } from "../modules/mod_logs"; import MessageCommandContext from "../../struct/MessageCommandContext"; +import CommandCategory from "../../struct/commands/CommandCategory"; export default { name: 'warn', aliases: null, removeEmptyArgs: false, description: 'add an infraction to an user\'s record', - category: 'moderation', + category: CommandCategory.Moderation, run: async (message: MessageCommandContext, args: string[]) => { if (!await isModerator(message)) return message.reply(NO_MANAGER_MSG); let user = await parseUserOrId(args.shift() ?? ''); @@ -46,4 +47,4 @@ export default { logModAction('warn', message.serverContext, message.member!, user._id, reason, infraction._id, `This is warn number ${userWarnCount} for this user.`), ]); } -} as Command; +} as SimpleCommand; diff --git a/bot/src/bot/commands/warns.ts b/bot/src/bot/commands/warns.ts index 6d2d4a7..3c41ec1 100644 --- a/bot/src/bot/commands/warns.ts +++ b/bot/src/bot/commands/warns.ts @@ -1,4 +1,4 @@ -import Command from "../../struct/Command"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import { client } from "../.."; import Infraction from "../../struct/antispam/Infraction"; import InfractionType from "../../struct/antispam/InfractionType"; @@ -8,6 +8,7 @@ import RelativeTime from 'dayjs/plugin/relativeTime'; import Xlsx from 'xlsx'; import { fetchUsername } from "../modules/mod_logs"; import MessageCommandContext from "../../struct/MessageCommandContext"; +import CommandCategory from "../../struct/commands/CommandCategory"; Day.extend(RelativeTime); @@ -16,7 +17,7 @@ export default { aliases: [ 'warnings', 'infractions', 'infraction' ], description: 'Show all user infractions', syntax: '/warns; /warns @username ["export-csv"]; /warns rm [ID]', - category: 'moderation', + category: CommandCategory.Moderation, run: async (message: MessageCommandContext, args: string[]) => { if (!await isModerator(message)) return message.reply(NO_MANAGER_MSG); @@ -122,7 +123,7 @@ export default { } } } -} as Command; +} as SimpleCommand; function getInfEmoji(inf: Infraction) { switch(inf.actionType) { diff --git a/bot/src/bot/commands/whitelist.ts b/bot/src/bot/commands/whitelist.ts index 0230632..071bd17 100644 --- a/bot/src/bot/commands/whitelist.ts +++ b/bot/src/bot/commands/whitelist.ts @@ -1,7 +1,8 @@ import { Message } from "@janderedev/revolt.js/dist/maps/Messages"; import { User } from "@janderedev/revolt.js/dist/maps/Users"; import { client } from "../.."; -import Command from "../../struct/Command"; +import CommandCategory from "../../struct/commands/CommandCategory"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import MessageCommandContext from "../../struct/MessageCommandContext"; import ServerConfig from "../../struct/ServerConfig"; import { isBotManager, NO_MANAGER_MSG, parseUser } from "../util"; @@ -13,7 +14,7 @@ export default { aliases: [], description: 'Allow users or roles to bypass moderation rules', syntax: SYNTAX, - category: 'configuration', + category: CommandCategory.Config, run: async (message: MessageCommandContext, args: string[]) => { let config: ServerConfig = await client.db.get('servers').findOne({ id: message.serverContext._id }) || {} if (!config.whitelist) config.whitelist = { users: [], roles: [], managers: true } @@ -113,4 +114,4 @@ export default { message.reply(`Command syntax: ${SYNTAX}`); } } -} as Command; +} as SimpleCommand; diff --git a/bot/src/bot/modules/command_handler.ts b/bot/src/bot/modules/command_handler.ts index 6cd713f..c0c6242 100644 --- a/bot/src/bot/modules/command_handler.ts +++ b/bot/src/bot/modules/command_handler.ts @@ -1,4 +1,4 @@ -import Command from "../../struct/Command"; +import SimpleCommand from "../../struct/commands/SimpleCommand"; import logger from "../logger"; import { client } from "../../index"; import fs from 'fs'; @@ -22,13 +22,13 @@ const DEFAULT_PREFIX = process.env['PREFIX'] ?? process.env['COMMAND_PREFIX'] ?? '/'; -let commands: Command[]; +let commands: SimpleCommand[]; (async () => { commands = (await Promise.all( fs.readdirSync(path.join(dirname, '..', 'commands')) .filter(file => file.endsWith('.js')) - .map(async file => await import(path.join(dirname, '..', 'commands', file)) as Command) + .map(async file => await import(path.join(dirname, '..', 'commands', file)) as SimpleCommand) )).map(c => (c as any).default) client.on('message/update', async msg => { diff --git a/bot/src/bot/util.ts b/bot/src/bot/util.ts index ce629e1..16953fe 100644 --- a/bot/src/bot/util.ts +++ b/bot/src/bot/util.ts @@ -115,6 +115,12 @@ async function getPermissionLevel(user: User|Member, server: Server): Promise<0| return 0; } +function getPermissionBasedOnRole(member: Member): 0|1|2|3 { + if (hasPerm(member, 'ManageServer')) return 3; + if (hasPerm(member, 'KickMembers')) return 1; + return 0; +} + function hasPerm(member: Member, perm: keyof typeof ServerPermission): boolean { let p = ServerPermission[perm]; if (member.server?.owner == member.user?._id) return true; @@ -308,6 +314,7 @@ export { isModerator, isBotManager, getPermissionLevel, + getPermissionBasedOnRole, parseUser, parseUserOrId, storeInfraction, diff --git a/bot/src/struct/Command.ts b/bot/src/struct/Command.ts deleted file mode 100644 index f201f9d..0000000 --- a/bot/src/struct/Command.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { ChannelPermission, ServerPermission } from "@janderedev/revolt.js"; - -class Command { - name: string; - aliases: string[] | null; - description: string | null; - syntax?: string | null; - restrict?: 'BOTOWNER' | null; - removeEmptyArgs?: boolean | null; - run: Function; - category?: string; - requiredPermissions?: { - server?: keyof typeof ServerPermission, - channel?: keyof typeof ChannelPermission, - } -} - -export default Command; diff --git a/bot/src/struct/CommandCategory.ts b/bot/src/struct/CommandCategory.ts deleted file mode 100644 index 5bacab4..0000000 --- a/bot/src/struct/CommandCategory.ts +++ /dev/null @@ -1,7 +0,0 @@ -class CommandCategory { - friendlyName: string; - description: string; - aliases: string[]; -} - -export default CommandCategory; diff --git a/bot/src/struct/commands/CommandCategory.ts b/bot/src/struct/commands/CommandCategory.ts new file mode 100644 index 0000000..4482b2f --- /dev/null +++ b/bot/src/struct/commands/CommandCategory.ts @@ -0,0 +1,9 @@ +enum CommandCategory { + Moderation = 'Moderation', + Config = 'Config', + Owner = 'Owner', + Misc = 'Misc', + None = 'None', +} + +export default CommandCategory; \ No newline at end of file diff --git a/bot/src/struct/commands/SimpleCommand.ts b/bot/src/struct/commands/SimpleCommand.ts new file mode 100644 index 0000000..bbfd229 --- /dev/null +++ b/bot/src/struct/commands/SimpleCommand.ts @@ -0,0 +1,35 @@ +import CommandCategory from "./CommandCategory"; +import MessageCommandContext from "../MessageCommandContext"; + +/** + * A basic command, consisting of basic attributes + * and a single run() function. + */ +class SimpleCommand { + // Primary name of the command. + name: string; + + // An array of alternative command names. + aliases: string[] | null; + + // The description is shown in /help. + description: string | null; + + // The syntax is shown in /help. + syntax?: string | null; + + // Restrict the command to bot owners. + restrict?: 'BOTOWNER' | null; + + // Unless explicitly set to false, the command handler will + // remove empty args (e.g. double spaces). + removeEmptyArgs?: boolean | null; + + // This is executed whenever the command is ran. + run: (message: MessageCommandContext, args: string[]) => Promise; + + // The category the command belongs to, used for /help. + category: CommandCategory; +} + +export default SimpleCommand;