From 1c6d451ffd63f9805b978e8565807e8a6b528681 Mon Sep 17 00:00:00 2001 From: IRONM00N <64110067+IRONM00N@users.noreply.github.com> Date: Thu, 29 Jul 2021 21:16:30 -0400 Subject: added a rudimentary automod, fixed a bunch of stuff, added some more listeners --- src/commands/dev/eval.ts | 2 - src/commands/info/avatar.ts | 3 +- src/commands/info/guildInfo.ts | 57 ++++--- src/commands/info/userInfo.ts | 18 +-- src/commands/moderation/slowmode.ts | 21 ++- src/commands/skyblock-reborn/chooseColor.ts | 179 +++++++++++++++++++++ src/commands/skyblock-reborn/chooseColorCommand.ts | 179 --------------------- 7 files changed, 239 insertions(+), 220 deletions(-) create mode 100644 src/commands/skyblock-reborn/chooseColor.ts delete mode 100644 src/commands/skyblock-reborn/chooseColorCommand.ts (limited to 'src/commands') diff --git a/src/commands/dev/eval.ts b/src/commands/dev/eval.ts index abdf2b9..4f6a293 100644 --- a/src/commands/dev/eval.ts +++ b/src/commands/dev/eval.ts @@ -86,10 +86,8 @@ export default class EvalCommand extends BushCommand { config = client.config, members = message.guild?.members, roles = message.guild?.roles, - client = client, emojis = util.emojis, colors = util.colors, - util = util, { ActivePunishment, Global, Guild, Level, ModLog, StickyRole } = await import('@lib'), { ButtonInteraction, diff --git a/src/commands/info/avatar.ts b/src/commands/info/avatar.ts index dc10f7d..4f7449b 100644 --- a/src/commands/info/avatar.ts +++ b/src/commands/info/avatar.ts @@ -43,9 +43,8 @@ export default class AvatarCommand extends BushCommand { const embed = new MessageEmbed() .setTimestamp() .setColor(util.colors.default) - .setTitle(user.tag) + .setTitle(`${user.tag}'s Avatar`) .setImage(user.avatarURL({ size: 2048, format: 'png', dynamic: true })); - await message.util.reply({ embeds: [embed] }); } } diff --git a/src/commands/info/guildInfo.ts b/src/commands/info/guildInfo.ts index e82a5fe..577086b 100644 --- a/src/commands/info/guildInfo.ts +++ b/src/commands/info/guildInfo.ts @@ -1,8 +1,7 @@ import { Argument, Constants } from 'discord-akairo'; -import { Guild, GuildPreview, MessageEmbed, Snowflake, Vanity } from 'discord.js'; +import { BaseGuildVoiceChannel, Guild, GuildPreview, MessageEmbed, Snowflake, Vanity } from 'discord.js'; import { BushCommand, BushMessage, BushSlashMessage } from '../../lib'; -// TODO: Implement regions and security export default class GuildInfoCommand extends BushCommand { public constructor() { super('guildInfo', { @@ -58,9 +57,9 @@ export default class GuildInfoCommand extends BushCommand { const guild: Guild | GuildPreview = (args?.guild as Guild | GuildPreview) || (message.guild as Guild); const emojis: string[] = []; const guildAbout: string[] = []; - // const guildSecurity = []; - if (['516977525906341928', '784597260465995796', '717176538717749358', '767448775450820639'].includes(guild.id)) - emojis.push(client.consts.mappings.otherEmojis.BUSH_VERIFIED); + const guildSecurity = []; + const verifiedGuilds = Object.values(client.consts.mappings.guilds); + if (verifiedGuilds.includes(guild.id)) emojis.push(client.consts.mappings.otherEmojis.BUSH_VERIFIED); if (!isPreview && guild instanceof Guild) { if (guild.premiumTier) emojis.push(client.consts.mappings.otherEmojis['BOOST_' + guild.premiumTier]); @@ -91,21 +90,29 @@ export default class GuildInfoCommand extends BushCommand { .size.toLocaleString()}` ]; - // TODO add guild regions - // const guildRegions = []; + const guildRegions = []; + guild.channels.cache.forEach((channel) => { + if (!channel.type.includes('VOICE')) return; + else if (!guildRegions.includes((channel as BaseGuildVoiceChannel).rtcRegion ?? 'automatic')) { + guildRegions.push((channel as BaseGuildVoiceChannel).rtcRegion ?? 'automatic'); + } + }); guildAbout.push( `**Owner:** ${guild.members.cache.get(guild.ownerId)?.user.tag}`, - `**Created** ${guild.createdAt.toLocaleString()}`, - `**Members:** ${guild.memberCount.toLocaleString()}`, - `**Online:** ${guild.approximatePresenceCount?.toLocaleString()}`, - `**Channels:** ${guild.channels.cache.size} (${channelTypes.join(', ')})`, - `**Emojis:** ${guild.emojis.cache.size.toLocaleString()}` - // `**Region:** ${guildRegions.join()}` + `**Created** ${guild.createdAt.toLocaleString()} (${util.dateDelta(guild.createdAt)})`, + `**Members:** ${guild.memberCount.toLocaleString() ?? 0}`, + `**Online:** ${guild.approximatePresenceCount?.toLocaleString() ?? 0}`, + `**Channels:** ${guild.channels.cache.size?.toLocaleString() ?? 0} (${channelTypes.join(', ')})`, + `**Emojis:** ${guild.emojis.cache.size?.toLocaleString() ?? 0}`, + `**Stickers:** ${guild.stickers.cache.size?.toLocaleString() ?? 0}`, + `**Regions:** ${guildRegions.map((region) => client.consts.mappings.regions[region] || region).join(', ')}` ); if (guild.premiumSubscriptionCount) guildAbout.push( - `**Boosts:** Level ${guild.premiumTier.slice(0, 4)} with ${guild.premiumSubscriptionCount ?? 0} boosts` + `**Boosts:** Level ${guild.premiumTier == 'NONE' ? '0' : guild.premiumTier[5]} with ${ + guild.premiumSubscriptionCount ?? 0 + } boosts` ); if (guild.me?.permissions.has('MANAGE_GUILD') && guild.vanityURLCode) { const vanityInfo: Vanity = await guild.fetchVanityData(); @@ -115,12 +122,22 @@ export default class GuildInfoCommand extends BushCommand { ); } - // guildSecurity.push; + guildSecurity.push( + `**Verification Level**: ${guild.verificationLevel.toLowerCase().replace(/_/g, ' ')}`, + `**Explicit Content Filter:** ${guild.explicitContentFilter.toLowerCase().replace(/_/g, ' ')}`, + `**Default Message Notifications:** ${ + typeof guild.defaultMessageNotifications === 'string' + ? guild.defaultMessageNotifications.toLowerCase().replace(/_/g, ' ') + : guild.defaultMessageNotifications + }`, + `**2FA Required**: ${guild.mfaLevel === 'ELEVATED' ? 'yes' : 'no'}` + ); } else { guildAbout.push( `**Members:** ${guild.approximateMemberCount?.toLocaleString()}`, `**Online:** ${guild.approximatePresenceCount?.toLocaleString()}`, - `**Emojis:** ${(guild as GuildPreview).emojis.size}` + `**Emojis:** ${(guild as GuildPreview).emojis.size?.toLocaleString() ?? 0}` + // `**Stickers:** ${(guild as GuildPreview).stickers.size}` ); } @@ -160,11 +177,11 @@ export default class GuildInfoCommand extends BushCommand { if (guildIcon) { guildInfoEmbed.setThumbnail(guildIcon); } - // if (!isPreview) { - // guildInfoEmbed.addField('» Security', guildSecurity.join('\n')); - // } + if (!isPreview) { + guildInfoEmbed.addField('» Security', guildSecurity.join('\n')); + } if (emojis) { - guildInfoEmbed.setDescription(emojis.join(' ')); + guildInfoEmbed.setDescription('\u200B' /*zero width space*/ + emojis.join(' ')); } return await message.util.reply({ embeds: [guildInfoEmbed] }); } diff --git a/src/commands/info/userInfo.ts b/src/commands/info/userInfo.ts index 87235a9..e36e92b 100644 --- a/src/commands/info/userInfo.ts +++ b/src/commands/info/userInfo.ts @@ -1,6 +1,5 @@ import { BushCommand, BushMessage, BushSlashMessage } from '@lib'; import { GuildMember, MessageEmbed } from 'discord.js'; -import moment from 'moment'; // TODO: Allow looking up a user not in the guild and not cached // TODO: Re-Implement Status Emojis @@ -78,11 +77,11 @@ export default class UserInfoCommand extends BushCommand { if (user.premiumSinceTimestamp) emojis.push(client.consts.mappings.otherEmojis.BOOSTER); const createdAt = user.user.createdAt.toLocaleString(), - createdAtDelta = moment(moment(user.user.createdAt).diff(moment())).toLocaleString(), + createdAtDelta = util.dateDelta(user.user.createdAt), joinedAt = user.joinedAt?.toLocaleString(), - joinedAtDelta = moment(user.joinedAt)?.diff(moment()).toLocaleString(), + joinedAtDelta = util.dateDelta(user.joinedAt, 2), premiumSince = user.premiumSince?.toLocaleString(), - premiumSinceDelta = moment(user.premiumSince)?.diff(moment()).toLocaleString(); + premiumSinceDelta = util.dateDelta(user.premiumSince, 2); // General Info const generalInfo = [ @@ -101,12 +100,12 @@ export default class UserInfoCommand extends BushCommand { if (premiumSince) serverUserInfo.push(`**Boosting Since:** ${premiumSince} (${premiumSinceDelta} ago)`); if (user.displayHexColor) serverUserInfo.push(`**Display Color:** ${user.displayHexColor}`); if (user.id == '322862723090219008' && message.guild.id == client.consts.mappings.guilds.bush) - serverUserInfo.push(`**General Deletions:** 2`); + serverUserInfo.push(`**General Deletions:** 1⅓`); if ( ['384620942577369088', '496409778822709251'].includes(user.id) && message.guild.id == client.consts.mappings.guilds.bush ) - serverUserInfo.push(`**General Deletions:** 1`); + serverUserInfo.push(`**General Deletions:** ⅓`); if (user.nickname) serverUserInfo.push(`**Nickname** ${user.nickname}`); if (serverUserInfo.length) userEmbed.addField('» Server Info', serverUserInfo.join('\n')).setColor(user.displayColor || util.colors.default); @@ -128,10 +127,11 @@ export default class UserInfoCommand extends BushCommand { if (user.presence.clientStatus) devices = Object.keys(user.presence.clientStatus); const presenceInfo = []; if (user.presence.status) presenceInfo.push(`**Status:** ${user.presence.status}`); - if (devices) presenceInfo.push(`**${devices.length - 1 ? 'Devices' : 'Device'}:** ${util.oxford(devices, 'and', '')}`); + if (devices && devices.length) + presenceInfo.push(`**${devices.length - 1 ? 'Devices' : 'Device'}:** ${util.oxford(devices, 'and', '')}`); if (activitiesNames.length) presenceInfo.push(`**Activit${activitiesNames.length - 1 ? 'ies' : 'y'}:** ${util.oxford(activitiesNames, 'and', '')}`); - if (customStatus) presenceInfo.push(`**Custom Status:** ${customStatus}`); + if (customStatus && customStatus.length) presenceInfo.push(`**Custom Status:** ${customStatus}`); userEmbed.addField('» Presence', presenceInfo.join('\n')); } @@ -148,7 +148,7 @@ export default class UserInfoCommand extends BushCommand { } if (perms.length) userEmbed.addField('» Important Perms', perms.join(' ')); - if (emojis) userEmbed.setDescription('​' /*zero width space*/ + emojis.join(' ')); + if (emojis) userEmbed.setDescription('\u200B' /*zero width space*/ + emojis.join(' ')); return await message.util.reply({ embeds: [userEmbed] }); } diff --git a/src/commands/moderation/slowmode.ts b/src/commands/moderation/slowmode.ts index f9ffbab..9b0d300 100644 --- a/src/commands/moderation/slowmode.ts +++ b/src/commands/moderation/slowmode.ts @@ -1,6 +1,6 @@ -import { BushCommand, BushMessage, BushSlashMessage } from '@lib'; -import { Argument, Constants } from 'discord-akairo'; -import { TextChannel, ThreadChannel } from 'discord.js'; +import { BushCommand, BushMessage, BushNewsChannel, BushSlashMessage, BushTextChannel, BushThreadChannel } from '@lib'; +import { Argument } from 'discord-akairo'; +import { NewsChannel, TextChannel, ThreadChannel } from 'discord.js'; export default class SlowModeCommand extends BushCommand { public constructor() { @@ -25,8 +25,7 @@ export default class SlowModeCommand extends BushCommand { }, { id: 'channel', - type: Constants.ArgumentTypes.CHANNEL, - match: Constants.ArgumentMatches.PHRASE, + type: 'channel', prompt: { start: 'What channel would you like to change?', retry: '{error} Choose a valid channel.', @@ -51,12 +50,18 @@ export default class SlowModeCommand extends BushCommand { public async exec( message: BushMessage | BushSlashMessage, - { length, channel }: { length: number | 'off' | 'none' | 'disable'; channel: TextChannel | ThreadChannel } + { + length, + channel + }: { + length: number | 'off' | 'none' | 'disable'; + channel: TextChannel | ThreadChannel | BushTextChannel | BushNewsChannel | BushThreadChannel | NewsChannel; + } ): Promise { if (message.channel.type === 'DM') return await message.util.reply(`${util.emojis.error} This command cannot be run in dms.`); - if (!channel) channel = message.channel as ThreadChannel | TextChannel; - if (!(channel instanceof TextChannel) || !(channel instanceof ThreadChannel)) + if (!channel) channel = message.channel; + if (!(channel instanceof TextChannel) && !(channel instanceof ThreadChannel)) return await message.util.reply(`${util.emojis.error} <#${channel.id}> is not a text or thread channel.`); if (length) { length = diff --git a/src/commands/skyblock-reborn/chooseColor.ts b/src/commands/skyblock-reborn/chooseColor.ts new file mode 100644 index 0000000..2b72301 --- /dev/null +++ b/src/commands/skyblock-reborn/chooseColor.ts @@ -0,0 +1,179 @@ +import { AllowedMentions, BushCommand, BushGuildMember, BushMessage, BushSlashMessage } from '@lib'; +import { Constants } from 'discord-akairo'; +import { CommandInteraction, Role, RoleResolvable, Snowflake } from 'discord.js'; + +const roleColorMap = [ + { + name: 'Brown', + value: '840952499883737108' + }, + { + name: 'Dark Red', + value: '840952434574229546' + }, + { + name: 'Red', + value: '840952208552230913' + }, + { + name: 'Pink', + value: '840952722681364531' + }, + { + name: 'Hot Pink', + value: '840952638309007412' + }, + { + name: 'Yellow', + value: '840952282598473778' + }, + { + name: 'Gold', + value: '840952256764313610' + }, + { + name: 'Light Green', + value: '846394838744170517' + }, + { + name: 'Green', + value: '840952308702642206' + }, + { + name: 'Sea Green', + value: '840952901853511690' + }, + { + name: 'Forest Green', + value: '840952382510858260' + }, + { + name: 'Dark Green', + value: '840952336339042315' + }, + { + name: 'Blue', + value: '840952833200750682' + }, + { + name: 'Dark Blue', + value: '840952875734532137' + }, + { + name: 'Blurple', + value: '853037502188617778' + }, + { + name: 'Wizard Purple', + value: '840952750816755723' + }, + { + name: 'White', + value: '840953158276743208' + }, + { + name: 'Dark Mode', + value: '840953434785710110' + }, + { + name: 'Black', + value: '840953275326660629' + } +]; +export default class ChooseColorCommand extends BushCommand { + public constructor() { + super('chooseColor', { + aliases: ['choosecolor'], + category: 'Skyblock: Reborn', + description: { + content: 'Choose a color.', + usage: 'color ', + examples: ['report IRONM00N'] + }, + args: [ + { + id: 'color', + type: 'role', + match: Constants.ArgumentMatches.REST, + prompt: { + start: 'Please choose a valid color.', + retry: `{error} Provide what did they do wrong.`, + optional: true + } + } + ], + clientPermissions: ['EMBED_LINKS', 'SEND_MESSAGES', 'MANAGE_ROLES'], + channel: 'guild', + restrictedGuilds: ['839287012409999391'], + slash: true, + slashGuilds: ['839287012409999391'], + slashOptions: [ + { + name: 'color', + description: 'The color you would like to have.', + type: 'STRING', + choices: roleColorMap, + required: true + } + ] + }); + } + + public async exec(message: BushMessage | BushSlashMessage, args: { color: Role | RoleResolvable }): Promise { + if (message.guild.id != client.consts.mappings.guilds.sbr) { + return await message.util.reply(`${util.emojis.error} This command can only be run in Skyblock: Reborn.`); + } + const allowedRoles: Snowflake[] = [ + '839317526395879449', //Server Booster + '840949387534008360' //Mega Donator + ]; + + if ( + !( + allowedRoles.some((role) => (message.member as BushGuildMember).roles.cache.has(role)) || + (message.member as BushGuildMember).permissions.has('ADMINISTRATOR') || + message.guild.ownerId === message.author.id + ) + ) { + const allowed = util.oxford( + allowedRoles.map((id) => `<@&${id}>s`), + 'and', + '' + ); + return await message.util.reply({ + content: `${util.emojis.error} Only ${allowed} can use this command.`, + allowedMentions: AllowedMentions.none(), + ephemeral: true + }); + } + if (message.util.isSlash) await (message.interaction as CommandInteraction).defer(); + // new Array( + // roleColorMap.map(obj => obj.name.toLowerCase()), + // roleColorMap.map(obj => obj.value) + // ); + const colorID = message.util.isSlash ? (args.color as string) : (args.color as Role).id; + if (!roleColorMap.map((obj) => obj.value).includes(colorID)) { + return await message.util.reply({ + content: `${util.emojis.error} ${args.color} is not a whitelisted color role.`, + allowedMentions: AllowedMentions.none() + }); + } + const memberColorRoles = (message.member as BushGuildMember).roles.cache.filter((role) => + roleColorMap.map((obj) => obj.value).includes(role.id) + ); + + await (message.member as BushGuildMember).roles.add(args.color, 'Choose Color Command.'); + + if (memberColorRoles.size) { + memberColorRoles.forEach( + (role) => (message.member as BushGuildMember).roles.remove(role), + 'Removing Duplicate Color Roles.' + ); + } + + return await message.util.reply({ + content: `${util.emojis.success} Assigned you the <@&${colorID}> role.`, + allowedMentions: AllowedMentions.none() + }); + } +} diff --git a/src/commands/skyblock-reborn/chooseColorCommand.ts b/src/commands/skyblock-reborn/chooseColorCommand.ts deleted file mode 100644 index 0138e36..0000000 --- a/src/commands/skyblock-reborn/chooseColorCommand.ts +++ /dev/null @@ -1,179 +0,0 @@ -import { AllowedMentions, BushCommand, BushGuildMember, BushMessage, BushSlashMessage } from '@lib'; -import { Constants } from 'discord-akairo'; -import { CommandInteraction, Role, RoleResolvable, Snowflake } from 'discord.js'; - -const roleColorMap = [ - { - name: 'Brown', - value: '840952499883737108' - }, - { - name: 'Dark Red', - value: '840952434574229546' - }, - { - name: 'Red', - value: '840952208552230913' - }, - { - name: 'Pink', - value: '840952722681364531' - }, - { - name: 'Hot Pink', - value: '840952638309007412' - }, - { - name: 'Yellow', - value: '840952282598473778' - }, - { - name: 'Gold', - value: '840952256764313610' - }, - { - name: 'Light Green', - value: '846394838744170517' - }, - { - name: 'Green', - value: '840952308702642206' - }, - { - name: 'Sea Green', - value: '840952901853511690' - }, - { - name: 'Forest Green', - value: '840952382510858260' - }, - { - name: 'Dark Green', - value: '840952336339042315' - }, - { - name: 'Blue', - value: '840952833200750682' - }, - { - name: 'Dark Blue', - value: '840952875734532137' - }, - { - name: 'Blurple', - value: '853037502188617778' - }, - { - name: 'Wizard Purple', - value: '840952750816755723' - }, - { - name: 'White', - value: '840953158276743208' - }, - { - name: 'Dark Mode', - value: '840953434785710110' - }, - { - name: 'Black', - value: '840953275326660629' - } -]; -export default class ChooseColorCommand extends BushCommand { - public constructor() { - super('chooseColor', { - aliases: ['choosecolor'], - category: 'Skyblock: Reborn', - description: { - content: 'Choose a color.', - usage: 'color ', - examples: ['report IRONM00N'] - }, - args: [ - { - id: 'color', - type: Constants.ArgumentTypes.ROLE, - match: Constants.ArgumentMatches.REST, - prompt: { - start: 'Please choose a valid color.', - retry: `{error} Provide what did they do wrong.`, - optional: true - } - } - ], - clientPermissions: ['EMBED_LINKS', 'SEND_MESSAGES'], - channel: 'guild', - restrictedGuilds: ['839287012409999391'], - slash: true, - slashGuilds: ['839287012409999391'], - slashOptions: [ - { - name: 'color', - description: 'The color you would like to have.', - type: 'STRING', - choices: roleColorMap, - required: true - } - ] - }); - } - - public async exec(message: BushMessage | BushSlashMessage, args: { color: Role | RoleResolvable }): Promise { - if (message.guild.id != client.consts.mappings.guilds.sbr) { - return await message.util.reply(`${util.emojis.error} This command can only be run in Skyblock: Reborn.`); - } - const allowedRoles: Snowflake[] = [ - '839317526395879449', //Server Booster - '840949387534008360' //Mega Donator - ]; - - if ( - !( - allowedRoles.some((role) => (message.member as BushGuildMember).roles.cache.has(role)) || - (message.member as BushGuildMember).permissions.has('ADMINISTRATOR') || - message.guild.ownerId === message.author.id - ) - ) { - const allowed = util.oxford( - allowedRoles.map((id) => `<@&${id}>s`), - 'and', - '' - ); - return await message.util.reply({ - content: `${util.emojis.error} Only ${allowed} can use this command.`, - allowedMentions: AllowedMentions.none(), - ephemeral: true - }); - } - if (message.util.isSlash) await (message.interaction as CommandInteraction).defer(); - // new Array( - // roleColorMap.map(obj => obj.name.toLowerCase()), - // roleColorMap.map(obj => obj.value) - // ); - const colorID = message.util.isSlash ? (args.color as string) : (args.color as Role).id; - if (!roleColorMap.map((obj) => obj.value).includes(colorID)) { - return await message.util.reply({ - content: `${util.emojis.error} ${args.color} is not a whitelisted color role.`, - allowedMentions: AllowedMentions.none() - }); - } - const memberColorRoles = (message.member as BushGuildMember).roles.cache.filter((role) => - roleColorMap.map((obj) => obj.value).includes(role.id) - ); - - await (message.member as BushGuildMember).roles.add(args.color, 'Choose Color Command.'); - - if (memberColorRoles.size) { - memberColorRoles.forEach( - (role) => (message.member as BushGuildMember).roles.remove(role), - 'Removing Duplicate Color Roles.' - ); - } - - return await message.util.reply({ - content: `${util.emojis.success} Assigned you the <@&${colorID}> role.`, - allowedMentions: AllowedMentions.none() - }); - } -} -- cgit