diff options
author | IRONM00N <64110067+IRONM00N@users.noreply.github.com> | 2022-01-06 12:28:26 -0500 |
---|---|---|
committer | IRONM00N <64110067+IRONM00N@users.noreply.github.com> | 2022-01-06 12:28:26 -0500 |
commit | a48dc88637d7b3e41a78eaeda91a19a967b278ff (patch) | |
tree | 6ef9f15683205fb10161c2db3d04fa35b2cc4238 | |
parent | 10331e32e00116a4a82b4f86f668aaffa5ca903d (diff) | |
download | tanzanite-a48dc88637d7b3e41a78eaeda91a19a967b278ff.tar.gz tanzanite-a48dc88637d7b3e41a78eaeda91a19a967b278ff.tar.bz2 tanzanite-a48dc88637d7b3e41a78eaeda91a19a967b278ff.zip |
fix a few things, add level roles (finally)
-rw-r--r-- | src/commands/config/_levelRoles.ts | 41 | ||||
-rw-r--r-- | src/commands/config/config.ts | 2 | ||||
-rw-r--r-- | src/commands/info/guildInfo.ts | 19 | ||||
-rw-r--r-- | src/commands/leveling/level.ts | 6 | ||||
-rw-r--r-- | src/commands/leveling/levelRoles.ts | 113 | ||||
-rw-r--r-- | src/lib/extensions/discord-akairo/BushCommand.ts | 11 | ||||
-rw-r--r-- | src/listeners/member-custom/bushLevelUpdate.ts | 20 |
7 files changed, 161 insertions, 51 deletions
diff --git a/src/commands/config/_levelRoles.ts b/src/commands/config/_levelRoles.ts deleted file mode 100644 index af7e637..0000000 --- a/src/commands/config/_levelRoles.ts +++ /dev/null @@ -1,41 +0,0 @@ -// import { BushCommand, type BushMessage, type BushSlashMessage } from '#lib'; - -// export default class LevelRolesCommand extends BushCommand { -// public constructor() { -// super('levelRole', { -// aliases: ['level-role', 'level-roles', 'lr'], -// category: 'config', -// description: 'Configure roles to be assigned to users upon reaching certain levels.', -// usage: ['level-role add <level> <role>', 'level-role remove <level>'], -// examples: ['level-role 1 2'], -// args: [ -// { -// id: 'required_argument', -// type: 'string', -// description: 'This is the first argument.', -// prompt: 'What would you like to set your first argument to be?', -// retry: '{error} Pick a valid argument.', -// slashType: 'STRING' -// }, -// { -// id: 'optional_argument', -// type: 'string', -// description: 'This is the second argument.', -// prompt: 'What would you like to set your second argument to be?', -// retry: '{error} Pick a valid argument.', -// optional: true, -// slashType: 'STRING' -// } -// ], -// slash: true, -// channel: 'guild', -// clientPermissions: (m) => util.clientSendAndPermCheck(m), -// userPermissions: ['MANAGE_GUILD', 'MANAGE_ROLES'] -// }); -// } - -// public override async exec( -// message: BushMessage | BushSlashMessage, -// args: { required_argument: string; optional_argument: string } -// ) {} -// } diff --git a/src/commands/config/config.ts b/src/commands/config/config.ts index c7da64f..9d8ba60 100644 --- a/src/commands/config/config.ts +++ b/src/commands/config/config.ts @@ -33,7 +33,7 @@ export default class ConfigCommand extends BushCommand { category: 'config', description: 'Configure server settings.', usage: [ - `settings (${settingsArr.map((s) => `\`${s}\``).join(', ')}) (${['view', 'set', 'add', 'remove'].map((s) => `\`${s}\``)})` + `settings (${settingsArr.map((s) => `'${s}'`).join(', ')}) (${['view', 'set', 'add', 'remove'].map((s) => `'${s}'`)})` ], examples: ['settings', 'config prefix set -'], slash: true, diff --git a/src/commands/info/guildInfo.ts b/src/commands/info/guildInfo.ts index e543eee..7d3d170 100644 --- a/src/commands/info/guildInfo.ts +++ b/src/commands/info/guildInfo.ts @@ -1,4 +1,5 @@ -import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, type ArgType, type BushMessage, type BushSlashMessage, type OptionalArgType } from '#lib'; +import assert from 'assert'; import { Constants, Guild, @@ -35,16 +36,20 @@ export default class GuildInfoCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage, args: { guild: ArgType<'guild'> | ArgType<'snowflake'> }) { - if (!args?.guild && !message.guild) { + public override async exec( + message: BushMessage | BushSlashMessage, + args: { guild: OptionalArgType<'guild'> | OptionalArgType<'snowflake'> } + ) { + if (!args.guild && !message.inGuild()) { return await message.util.reply( `${util.emojis.error} You must either provide an server to provide info about or run this command in a server.` ); } + const otherEmojis = client.consts.mappings.otherEmojis; let isPreview = false; - let _guild: ArgType<'guild'> | ArgType<'snowflake'> | GuildPreview = args.guild; - if (['number', 'string'].includes(typeof args?.guild)) { + let _guild: ArgType<'guild'> | ArgType<'snowflake'> | GuildPreview = args.guild ?? message.guild!; + if (typeof _guild === 'string') { const preview = await client.fetchGuildPreview(`${args.guild}` as Snowflake).catch(() => {}); if (preview) { _guild = preview; @@ -53,7 +58,9 @@ export default class GuildInfoCommand extends BushCommand { return await message.util.reply(`${util.emojis.error} That guild is not discoverable or does not exist.`); } } - const guild: Guild | GuildPreview = (_guild as Guild | GuildPreview) || (_guild as Guild); + + const guild: Guild | GuildPreview = _guild; + assert(guild); const emojis: string[] = []; const guildAbout: string[] = []; const guildStats: string[] = []; diff --git a/src/commands/leveling/level.ts b/src/commands/leveling/level.ts index 61672a3..be52a5d 100644 --- a/src/commands/leveling/level.ts +++ b/src/commands/leveling/level.ts @@ -3,11 +3,11 @@ import { BushCommand, CanvasProgressBar, Level, - type ArgType, type BushGuild, type BushMessage, type BushSlashMessage, - type BushUser + type BushUser, + type OptionalArgType } from '#lib'; import { SimplifyNumber } from '@notenoughupdates/simplify-number'; import assert from 'assert'; @@ -46,7 +46,7 @@ export default class LevelCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage, args: { user?: ArgType<'user'> }) { + public override async exec(message: BushMessage | BushSlashMessage, args: { user: OptionalArgType<'user'> }) { if (!message.guild) return await message.util.reply(`${util.emojis.error} This command can only be run in a server.`); if (!(await message.guild.hasFeature('leveling'))) return await message.util.reply( diff --git a/src/commands/leveling/levelRoles.ts b/src/commands/leveling/levelRoles.ts new file mode 100644 index 0000000..a5eb5c4 --- /dev/null +++ b/src/commands/leveling/levelRoles.ts @@ -0,0 +1,113 @@ +import { AllowedMentions, BushCommand, type ArgType, type BushMessage, type BushSlashMessage, type OptionalArgType } from '#lib'; +import assert from 'assert'; + +export default class LevelRolesCommand extends BushCommand { + public constructor() { + super('levelRole', { + aliases: ['level-role', 'level-roles', 'lr'], + category: 'config', + description: 'Configure roles to be assigned to users upon reaching certain levels.', + note: 'Omit the role to remove the role. View configured roles with `-config levelRoles`.', + usage: ['level-role <level> [role]'], + examples: ['level-role 100 @Super Cool Role'], + args: [ + { + id: 'level', + type: 'integer', + description: 'The level to assign the role when reached.', + prompt: 'What level would you like to set a role for when reached?', + retry: '{error} Pick a valid integer representing the role to assign a role to when reached.', + slashType: 'INTEGER' + }, + { + id: 'role', + type: 'role', + match: 'rest', + description: 'The role to assign to a user who reaches the specified level.', + prompt: 'What role would you like to assign to users when they reach that level?', + retry: '{error} Choose a valid role to assign to users upon reaching the specified level.', + slashType: 'ROLE', + optional: true + } + ], + slash: true, + channel: 'guild', + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['MANAGE_ROLES']), + userPermissions: ['MANAGE_GUILD', 'MANAGE_ROLES'] + }); + } + + public override async exec( + message: BushMessage | BushSlashMessage, + args: { level: ArgType<'integer'>; role: OptionalArgType<'role'> } + ) { + assert(message.inGuild()); + assert(message.member); + + if (!(await message.guild.hasFeature('leveling'))) { + return await message.util.reply( + `${util.emojis.error} This command can only be run in servers with the leveling feature enabled.` + ); + } + + if (args.level < 1) return await message.util.reply(`${util.emojis.error} You cannot set a level role less that 1.`); + + if (args.role) { + if (args.role.managed) + return await message.util.reply({ + content: `${util.emojis.error} You cannot set <@${args.role.id}> as a level role since it is managed.`, + allowedMentions: AllowedMentions.none() + }); + else if (args.role.id === message.guild.id) + return await message.util.reply({ + content: `${util.emojis.error} You cannot set the @everyone role as a level role.`, + allowedMentions: AllowedMentions.none() + }); + else if (args.role.comparePositionTo(message.member.roles.highest) >= 0) + return await message.util.reply({ + content: `${util.emojis.error} <@${args.role.id}> is higher or equal to your highest role.`, + allowedMentions: AllowedMentions.none() + }); + else if (args.role.comparePositionTo(message.guild.me!.roles.highest) >= 0) + return await message.util.reply({ + content: `${util.emojis.error} <@${args.role.id}> is higher or equal to my highest role.`, + allowedMentions: AllowedMentions.none() + }); + } + + const oldRoles = Object.freeze(await message.guild.getSetting('levelRoles')); + const newRoles = { ...oldRoles }; + + if (args.role) { + newRoles[args.level] = args.role.id; + } else { + delete newRoles[args.level]; + } + Object.freeze(newRoles); + + const success = await message.guild.setSetting('levelRoles', newRoles).catch(() => false); + + if (!success) return await message.util.reply(`${util.emojis.error} An error occurred while setting the level roles.`); + + if (!oldRoles[args.level] && newRoles[args.level]) { + return await message.util.reply({ + content: `${util.emojis.success} The level role for **${args.level}** is now <@&${newRoles[args.level]}>.`, + allowedMentions: AllowedMentions.none() + }); + } else if (oldRoles[args.level] && !newRoles[args.level]) { + return await message.util.reply({ + content: `${util.emojis.success} The level role for **${args.level}** was <@&${ + oldRoles[args.level] + }> but is now disabled.`, + allowedMentions: AllowedMentions.none() + }); + } else if (oldRoles[args.level] && newRoles[args.level]) { + return await message.util.reply({ + content: `${util.emojis.success} The level role for **${args.level}** has been updated from <@&${ + oldRoles[args.level] + }> to <@&${newRoles[args.level]}>.`, + allowedMentions: AllowedMentions.none() + }); + } + } +} diff --git a/src/lib/extensions/discord-akairo/BushCommand.ts b/src/lib/extensions/discord-akairo/BushCommand.ts index 782fae5..fb488be 100644 --- a/src/lib/extensions/discord-akairo/BushCommand.ts +++ b/src/lib/extensions/discord-akairo/BushCommand.ts @@ -290,6 +290,11 @@ interface ExtendedCommandOptions { * Use instead of {@link BaseBushCommandOptions.args} when using argument generators or custom slashOptions */ helpArgs?: BushArgumentOptions[]; + + /** + * Extra information about the command, displayed in the help command. + */ + note?: string; } export interface BaseBushCommandOptions @@ -397,6 +402,11 @@ export class BushCommand extends Command { */ public argsInfo?: ArgsInfo[]; + /** + * Extra information about the command, displayed in the help command. + */ + public note?: string; + public constructor(id: string, options: BushCommandOptions) { const options_ = options as BaseBushCommandOptions; @@ -501,6 +511,7 @@ export class BushCommand extends Command { this.restrictedGuilds = options_.restrictedGuilds; this.pseudo = !!options_.pseudo; this.bypassChannelBlacklist = !!options_.bypassChannelBlacklist; + this.note = options_.note; } } diff --git a/src/listeners/member-custom/bushLevelUpdate.ts b/src/listeners/member-custom/bushLevelUpdate.ts index 18b0fc2..6299a36 100644 --- a/src/listeners/member-custom/bushLevelUpdate.ts +++ b/src/listeners/member-custom/bushLevelUpdate.ts @@ -24,5 +24,25 @@ export default class BushLevelUpdateListener extends BushListener { if (!success) await client.console.warn('bushLevelUpdate', `Could not send level up message in ${message.guild}`); })(); } + void (async () => { + const levelRoles = await message.guild.getSetting('levelRoles'); + if (Object.keys(levelRoles).length) { + const promises = []; + for (let i = 0; i < newLevel; i++) { + if (levelRoles[i]) { + if (member.roles.cache.has(levelRoles[i])) continue; + else promises.push(member.roles.add(levelRoles[i])); + } + } + try { + if (promises.length) await Promise.all(promises); + } catch (e) { + await member.guild.error( + 'bushLevelUpdate', + `There was an error adding level roles to ${member.user.tag} upon reaching to level ${newLevel}.\n${e?.message ?? e}` + ); + } + } + })(); } } |