From 9a1a2a6852298069ffde603250fcbf3c9b135a7d Mon Sep 17 00:00:00 2001 From: smyalygames Date: Fri, 10 Feb 2023 13:20:07 +0000 Subject: [PATCH 01/13] feat(arabot): add button for managing access to non vegan section --- src/interaction-handlers/nonVeganAccess.ts | 86 ++++++++++++++++++++++ src/listeners/nonVeganAccess.ts | 78 ++++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 src/interaction-handlers/nonVeganAccess.ts create mode 100644 src/listeners/nonVeganAccess.ts diff --git a/src/interaction-handlers/nonVeganAccess.ts b/src/interaction-handlers/nonVeganAccess.ts new file mode 100644 index 0000000..5160d43 --- /dev/null +++ b/src/interaction-handlers/nonVeganAccess.ts @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +/* + Animal Rights Advocates Discord Bot + Copyright (C) 2023 Anthony Berg + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +import { InteractionHandler, InteractionHandlerTypes, PieceContext } from '@sapphire/framework'; +import type { ButtonInteraction, GuildMember } from 'discord.js'; +import IDs from '#utils/ids'; + +export class NonVeganAccessButtonHandler extends InteractionHandler { + public constructor(ctx: PieceContext, options: InteractionHandler.Options) { + super(ctx, { + ...options, + interactionHandlerType: InteractionHandlerTypes.Button, + }); + } + + public override parse(interaction: ButtonInteraction) { + if (interaction.customId !== 'nvAccess') return this.none(); + + return this.some(); + } + + public async run(interaction: ButtonInteraction) { + let { member } = interaction; + + const errorMessage = 'There was an error giving you the role, please try again later or contact ModMail/the developer' + + 'to sort out this problem.'; + + if (member === null) { + await interaction.reply({ + content: errorMessage, + ephemeral: true, + }); + return; + } + + try { + member = member as GuildMember; + + if (!member.roles.cache.has(IDs.roles.vegan.vegan)) { + await interaction.reply({ + content: 'You need to be vegan to use this button!', + ephemeral: true, + }); + return; + } + + if (member.roles.cache.has(IDs.roles.vegan.activist)) { + await member.roles.remove(IDs.roles.vegan.activist); + await interaction.reply({ + content: 'Your access from the non vegan section has been removed successfully. ' + + 'If you want to gain access again, click this button again.', + ephemeral: true, + }); + return; + } + + await member.roles.add(IDs.roles.vegan.activist); + await interaction.reply({ + content: 'Your access to the non vegan section has been given back successfully. ' + + 'If you want to remove access again, click this button again.', + ephemeral: true, + }); + } catch (error) { + await interaction.reply({ + content: errorMessage, + ephemeral: true, + }); + } + } +} diff --git a/src/listeners/nonVeganAccess.ts b/src/listeners/nonVeganAccess.ts new file mode 100644 index 0000000..89243f4 --- /dev/null +++ b/src/listeners/nonVeganAccess.ts @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +/* + Animal Rights Advocates Discord Bot + Copyright (C) 2023 Anthony Berg + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +import { Listener } from '@sapphire/framework'; +import { ButtonStyle, ActionRowBuilder, ButtonBuilder } from 'discord.js'; + +import type { + Client, + TextChannel, +} from 'discord.js'; +import IDs from '#utils/ids'; + +export class NonVeganAccessReady extends Listener { + public constructor(context: Listener.Context, options: Listener.Options) { + super(context, { + ...options, + once: true, + event: 'ready', + }); + } + + public async run(client: Client) { + let roles = client.channels.cache + .get(IDs.channels.information.roles) as TextChannel | undefined; + if (roles === undefined) { + roles = await client.channels + .fetch(IDs.channels.information.roles) as TextChannel | undefined; + if (roles === undefined) { + this.container.logger.error('nonVeganAccess: Roles not found'); + return; + } + } + + const botId = this.container.client.id; + const messages = await roles.messages.fetch(); + const message = messages.first(); + + const content = 'If you\'re vegan want your access removed/added back to the non vegan sections' + + 'press the button bellow to gain/remove access to the non vegan sections.'; + + const button = new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId('nvAccess') + .setLabel('Non Vegan Access') + .setStyle(ButtonStyle.Secondary), + ); + + if (message?.author.id !== botId) { + await roles.send({ + content, + components: [button], + }); + } else if (message?.author.id === botId && message?.components.length < 1) { + await message.delete(); + await roles.send({ + content, + components: [button], + }); + } + } +} From a45a297d2fcbb1ea4fd4cf954ffae75d9f7afd25 Mon Sep 17 00:00:00 2001 From: smyalygames Date: Sat, 18 Feb 2023 13:19:28 +0000 Subject: [PATCH 02/13] refactor(arabot): remove duplicate code for creating channels --- src/listeners/verification/joinVC.ts | 262 +++++++++++---------------- 1 file changed, 105 insertions(+), 157 deletions(-) diff --git a/src/listeners/verification/joinVC.ts b/src/listeners/verification/joinVC.ts index f5489d3..d5c7b3b 100644 --- a/src/listeners/verification/joinVC.ts +++ b/src/listeners/verification/joinVC.ts @@ -26,7 +26,7 @@ import type { VoiceState, GuildMember, Guild, - User, + User, VoiceBasedChannel, } from 'discord.js'; import { time, @@ -139,73 +139,20 @@ export class VerificationJoinVCListener extends Listener { .filter((c) => c.type === ChannelType.GuildVoice); // Create a text channel for verifiers only - // Checks if there are more than 10 voice channels if (!verifier) { - // TODO refactor this mess to circumvent - // "Contains words not allowed for servers in Server Discovery." let verificationText: TextChannel; let bannedName = false; try { - verificationText = await guild.channels.create({ - name: `✅┃${member.displayName}-verification`, - type: ChannelType.GuildText, - topic: `Channel for verifiers only. ${member.id} ${channel.id} (Please do not change this)`, - parent: category.id, - userLimit: 1, - permissionOverwrites: [ - { - id: guild.roles.everyone, - deny: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel], - }, - { - id: IDs.roles.verifyBlock, - deny: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel], - }, - { - id: IDs.roles.staff.verifier, - allow: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel], - }, - { - id: IDs.roles.staff.trialVerifier, - allow: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel], - }, - ], - }); + verificationText = await this.createTextChannel(member, channel, category, guild); } catch { - verificationText = await guild.channels.create({ - name: `✅┃${member.displayName}-verification`, - type: ChannelType.GuildText, - topic: `Channel for verifiers only. ${member.id} ${channel.id} (Please do not change this)`, - parent: category.id, - userLimit: 1, - permissionOverwrites: [ - { - id: guild.roles.everyone, - deny: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel], - }, - { - id: IDs.roles.verifyBlock, - deny: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel], - }, - { - id: IDs.roles.staff.verifier, - allow: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel], - }, - { - id: IDs.roles.staff.trialVerifier, - allow: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel], - }, - ], - }); bannedName = true; + verificationText = await this.createTextChannel( + member, + channel, + category, + guild, + bannedName, + ); } if (!bannedName) { @@ -230,102 +177,9 @@ export class VerificationJoinVCListener extends Listener { // Checks if there are more than 10 voice channels if (listVoiceChannels.size > maxVCs - 1) { - await guild.channels.create({ - name: 'Verification', - type: ChannelType.GuildVoice, - parent: category.id, - userLimit: 1, - permissionOverwrites: [ - { - id: guild.roles.everyone, - deny: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.Stream], - }, - { - id: IDs.roles.verifyBlock, - deny: [PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.Connect, - PermissionsBitField.Flags.SendMessages], - }, - { - id: IDs.roles.nonvegan.nonvegan, - allow: [PermissionsBitField.Flags.ViewChannel], - deny: [PermissionsBitField.Flags.Connect], - }, - { - id: IDs.roles.vegan.vegan, - allow: [PermissionsBitField.Flags.ViewChannel], - deny: [PermissionsBitField.Flags.Connect], - }, - { - id: IDs.roles.vegan.activist, - deny: [PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.Connect], - }, - { - id: IDs.roles.staff.verifier, - allow: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.Connect, - PermissionsBitField.Flags.MuteMembers], - }, - { - id: IDs.roles.staff.trialVerifier, - allow: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.Connect, - PermissionsBitField.Flags.MuteMembers], - }, - ], - }); + await this.createVoiceChannel(guild, category, true); } else { - await guild.channels.create({ - name: 'Verification', - type: ChannelType.GuildVoice, - parent: category.id, - userLimit: 1, - permissionOverwrites: [ - { - id: guild.roles.everyone, - deny: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.SendMessages], - }, - { - id: IDs.roles.verifyBlock, - deny: [PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.Connect, - PermissionsBitField.Flags.SendMessages], - }, - { - id: IDs.roles.nonvegan.nonvegan, - allow: [PermissionsBitField.Flags.ViewChannel], - }, - { - id: IDs.roles.vegan.vegan, - allow: [PermissionsBitField.Flags.ViewChannel], - }, - { - id: IDs.roles.vegan.activist, - deny: [PermissionsBitField.Flags.ViewChannel, PermissionsBitField.Flags.Connect], - }, - { - id: IDs.roles.staff.verifier, - allow: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.Connect, - PermissionsBitField.Flags.MuteMembers], - }, - { - id: IDs.roles.staff.trialVerifier, - allow: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.Connect, - PermissionsBitField.Flags.MuteMembers], - }, - ], - }); + await this.createVoiceChannel(guild, category); } // Change permissions to join the current channel @@ -364,6 +218,100 @@ export class VerificationJoinVCListener extends Listener { await currentChannel.setUserLimit(0); } + private async createTextChannel( + member: GuildMember, + voiceChannel: VoiceBasedChannel, + category: CategoryChannel, + guild: Guild, + bannedName = false, + ) { + const channel = await guild.channels.create({ + name: `✅┃${!bannedName ? member.displayName : member.id}-verification`, + type: ChannelType.GuildText, + topic: `Channel for verifiers only. ${member.id} ${voiceChannel.id} (Please do not change this)`, + parent: category.id, + userLimit: 1, + permissionOverwrites: [ + { + id: guild.roles.everyone, + deny: [PermissionsBitField.Flags.SendMessages, + PermissionsBitField.Flags.ViewChannel], + }, + { + id: IDs.roles.verifyBlock, + deny: [PermissionsBitField.Flags.SendMessages, + PermissionsBitField.Flags.ViewChannel], + }, + { + id: IDs.roles.staff.verifier, + allow: [PermissionsBitField.Flags.SendMessages, + PermissionsBitField.Flags.ViewChannel], + }, + { + id: IDs.roles.staff.trialVerifier, + allow: [PermissionsBitField.Flags.SendMessages, + PermissionsBitField.Flags.ViewChannel], + }, + ], + }); + return channel; + } + + private async createVoiceChannel(guild: Guild, category: CategoryChannel, full = false) { + const channel = await guild.channels.create({ + name: 'Verification', + type: ChannelType.GuildVoice, + parent: category.id, + userLimit: 1, + permissionOverwrites: [ + { + id: guild.roles.everyone, + deny: [PermissionsBitField.Flags.SendMessages, + PermissionsBitField.Flags.ViewChannel, + PermissionsBitField.Flags.Stream], + }, + { + id: IDs.roles.verifyBlock, + deny: [PermissionsBitField.Flags.ViewChannel, + PermissionsBitField.Flags.Connect, + PermissionsBitField.Flags.SendMessages], + }, + { + id: IDs.roles.nonvegan.nonvegan, + allow: [PermissionsBitField.Flags.ViewChannel], + }, + { + id: IDs.roles.vegan.vegan, + allow: [PermissionsBitField.Flags.ViewChannel], + }, + { + id: IDs.roles.vegan.activist, + deny: [PermissionsBitField.Flags.ViewChannel, + PermissionsBitField.Flags.Connect], + }, + { + id: IDs.roles.staff.verifier, + allow: [PermissionsBitField.Flags.SendMessages, + PermissionsBitField.Flags.ViewChannel, + PermissionsBitField.Flags.Connect, + PermissionsBitField.Flags.MuteMembers], + }, + { + id: IDs.roles.staff.trialVerifier, + allow: [PermissionsBitField.Flags.SendMessages, + PermissionsBitField.Flags.ViewChannel, + PermissionsBitField.Flags.Connect, + PermissionsBitField.Flags.MuteMembers], + }, + ], + }); + + if (full) { + await channel.permissionOverwrites.edit(IDs.roles.nonvegan.nonvegan, { Connect: false }); + await channel.permissionOverwrites.edit(IDs.roles.vegan.vegan, { Connect: false }); + } + } + // Creates an embed for information about the user private async getUserInfo(user: GuildMember, roles: string) { const joinTime = time(user.joinedAt!); From 12d44454284b77e7f3db4213c3393729be59b957 Mon Sep 17 00:00:00 2001 From: smyalygames Date: Sat, 18 Feb 2023 13:31:58 +0000 Subject: [PATCH 03/13] refactor(arabot): remove duplicate code for creating channels --- src/listeners/verification/joinVC.ts | 106 ++------------------- src/listeners/verification/leaveVC.ts | 50 +--------- src/listeners/verification/start.ts | 50 +--------- src/utils/verification.ts | 127 ++++++++++++++++++++++++++ 4 files changed, 139 insertions(+), 194 deletions(-) create mode 100644 src/utils/verification.ts diff --git a/src/listeners/verification/joinVC.ts b/src/listeners/verification/joinVC.ts index d5c7b3b..f504ef6 100644 --- a/src/listeners/verification/joinVC.ts +++ b/src/listeners/verification/joinVC.ts @@ -26,7 +26,7 @@ import type { VoiceState, GuildMember, Guild, - User, VoiceBasedChannel, + User, } from 'discord.js'; import { time, @@ -38,6 +38,7 @@ import { ActionRowBuilder, EmbedBuilder, } from 'discord.js'; +import { createVerificationText, createVerificationVoice } from '#utils/verification'; import { maxVCs, questionInfo, serverFind } from '#utils/verificationConfig'; import { joinVerification, startVerification, finishVerification } from '#utils/database/verification'; import { findNotes } from '#utils/database/sus'; @@ -143,14 +144,13 @@ export class VerificationJoinVCListener extends Listener { let verificationText: TextChannel; let bannedName = false; try { - verificationText = await this.createTextChannel(member, channel, category, guild); + verificationText = await createVerificationText(member, channel, category); } catch { bannedName = true; - verificationText = await this.createTextChannel( + verificationText = await createVerificationText( member, channel, category, - guild, bannedName, ); } @@ -177,9 +177,9 @@ export class VerificationJoinVCListener extends Listener { // Checks if there are more than 10 voice channels if (listVoiceChannels.size > maxVCs - 1) { - await this.createVoiceChannel(guild, category, true); + await createVerificationVoice(category, true); } else { - await this.createVoiceChannel(guild, category); + await createVerificationVoice(category); } // Change permissions to join the current channel @@ -218,100 +218,6 @@ export class VerificationJoinVCListener extends Listener { await currentChannel.setUserLimit(0); } - private async createTextChannel( - member: GuildMember, - voiceChannel: VoiceBasedChannel, - category: CategoryChannel, - guild: Guild, - bannedName = false, - ) { - const channel = await guild.channels.create({ - name: `✅┃${!bannedName ? member.displayName : member.id}-verification`, - type: ChannelType.GuildText, - topic: `Channel for verifiers only. ${member.id} ${voiceChannel.id} (Please do not change this)`, - parent: category.id, - userLimit: 1, - permissionOverwrites: [ - { - id: guild.roles.everyone, - deny: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel], - }, - { - id: IDs.roles.verifyBlock, - deny: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel], - }, - { - id: IDs.roles.staff.verifier, - allow: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel], - }, - { - id: IDs.roles.staff.trialVerifier, - allow: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel], - }, - ], - }); - return channel; - } - - private async createVoiceChannel(guild: Guild, category: CategoryChannel, full = false) { - const channel = await guild.channels.create({ - name: 'Verification', - type: ChannelType.GuildVoice, - parent: category.id, - userLimit: 1, - permissionOverwrites: [ - { - id: guild.roles.everyone, - deny: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.Stream], - }, - { - id: IDs.roles.verifyBlock, - deny: [PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.Connect, - PermissionsBitField.Flags.SendMessages], - }, - { - id: IDs.roles.nonvegan.nonvegan, - allow: [PermissionsBitField.Flags.ViewChannel], - }, - { - id: IDs.roles.vegan.vegan, - allow: [PermissionsBitField.Flags.ViewChannel], - }, - { - id: IDs.roles.vegan.activist, - deny: [PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.Connect], - }, - { - id: IDs.roles.staff.verifier, - allow: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.Connect, - PermissionsBitField.Flags.MuteMembers], - }, - { - id: IDs.roles.staff.trialVerifier, - allow: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.Connect, - PermissionsBitField.Flags.MuteMembers], - }, - ], - }); - - if (full) { - await channel.permissionOverwrites.edit(IDs.roles.nonvegan.nonvegan, { Connect: false }); - await channel.permissionOverwrites.edit(IDs.roles.vegan.vegan, { Connect: false }); - } - } - // Creates an embed for information about the user private async getUserInfo(user: GuildMember, roles: string) { const joinTime = time(user.joinedAt!); diff --git a/src/listeners/verification/leaveVC.ts b/src/listeners/verification/leaveVC.ts index e110d71..ea33c8f 100644 --- a/src/listeners/verification/leaveVC.ts +++ b/src/listeners/verification/leaveVC.ts @@ -21,7 +21,8 @@ import { Listener } from '@sapphire/framework'; import type { VoiceState, CategoryChannel, VoiceChannel, TextChannel, } from 'discord.js'; -import { time, ChannelType, PermissionsBitField } from 'discord.js'; +import { time, ChannelType } from 'discord.js'; +import { createVerificationVoice } from '#utils/verification'; import { maxVCs, leaveBan } from '#utils/verificationConfig'; import { getUser, checkFinish, countIncomplete } from '#utils/database/verification'; import { fetchRoles } from '#utils/database/dbExistingUser'; @@ -126,52 +127,7 @@ export class VerificationLeaveVCListener extends Listener { // If there are no VCs left in verification after having the channel deleted if (listVoiceChannels.size - 1 === 0) { // Create a verification channel - await guild.channels.create({ - name: 'Verification', - type: ChannelType.GuildVoice, - parent: category.id, - userLimit: 1, - permissionOverwrites: [ - { - id: guild.roles.everyone, - deny: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.SendMessages], - }, - { - id: IDs.roles.verifyBlock, - deny: [PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.Connect, - PermissionsBitField.Flags.SendMessages], - }, - { - id: IDs.roles.nonvegan.nonvegan, - allow: [PermissionsBitField.Flags.ViewChannel], - }, - { - id: IDs.roles.vegan.vegan, - allow: [PermissionsBitField.Flags.ViewChannel], - }, - { - id: IDs.roles.vegan.activist, - deny: [PermissionsBitField.Flags.ViewChannel, PermissionsBitField.Flags.Connect], - }, - { - id: IDs.roles.staff.verifier, - allow: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.Connect, - PermissionsBitField.Flags.MuteMembers], - }, - { - id: IDs.roles.staff.trialVerifier, - allow: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.Connect, - PermissionsBitField.Flags.MuteMembers], - }, - ], - }); + await createVerificationVoice(category); } // If there are less than 10, stop diff --git a/src/listeners/verification/start.ts b/src/listeners/verification/start.ts index 9500a01..afe081f 100644 --- a/src/listeners/verification/start.ts +++ b/src/listeners/verification/start.ts @@ -24,7 +24,8 @@ import type { TextChannel, VoiceChannel, } from 'discord.js'; -import { ChannelType, PermissionsBitField } from 'discord.js'; +import { ChannelType } from 'discord.js'; +import { createVerificationVoice } from '#utils/verification'; import IDs from '#utils/ids'; export class VerificationReady extends Listener { @@ -84,52 +85,7 @@ export class VerificationReady extends Listener { } }); if (!verification) { - await category.guild.channels.create({ - name: 'Verification', - type: ChannelType.GuildVoice, - parent: category.id, - userLimit: 1, - permissionOverwrites: [ - { - id: category.guild.roles.everyone, - deny: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.SendMessages], - }, - { - id: IDs.roles.verifyBlock, - deny: [PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.Connect, - PermissionsBitField.Flags.SendMessages], - }, - { - id: IDs.roles.nonvegan.nonvegan, - allow: [PermissionsBitField.Flags.ViewChannel], - }, - { - id: IDs.roles.vegan.vegan, - allow: [PermissionsBitField.Flags.ViewChannel], - }, - { - id: IDs.roles.vegan.activist, - deny: [PermissionsBitField.Flags.ViewChannel, PermissionsBitField.Flags.Connect], - }, - { - id: IDs.roles.staff.verifier, - allow: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.Connect, - PermissionsBitField.Flags.MuteMembers], - }, - { - id: IDs.roles.staff.trialVerifier, - allow: [PermissionsBitField.Flags.SendMessages, - PermissionsBitField.Flags.ViewChannel, - PermissionsBitField.Flags.Connect, - PermissionsBitField.Flags.MuteMembers], - }, - ], - }); + await createVerificationVoice(category); } } } diff --git a/src/utils/verification.ts b/src/utils/verification.ts new file mode 100644 index 0000000..e752249 --- /dev/null +++ b/src/utils/verification.ts @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +/* + Animal Rights Advocates Discord Bot + Copyright (C) 2022 Anthony Berg + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +import { + CategoryChannel, + ChannelType, + GuildMember, + PermissionsBitField, + VoiceBasedChannel, +} from 'discord.js'; +import IDs from '#utils/ids'; + +export async function createVerificationText( + member: GuildMember, + voiceChannel: VoiceBasedChannel, + category: CategoryChannel, + bannedName = false, +) { + const { guild } = category; + + const channel = await guild.channels.create({ + name: `✅┃${!bannedName ? member.displayName : member.id}-verification`, + type: ChannelType.GuildText, + topic: `Channel for verifiers only. ${member.id} ${voiceChannel.id} (Please do not change this)`, + parent: category.id, + userLimit: 1, + permissionOverwrites: [ + { + id: guild.roles.everyone, + deny: [PermissionsBitField.Flags.SendMessages, + PermissionsBitField.Flags.ViewChannel], + }, + { + id: IDs.roles.verifyBlock, + deny: [PermissionsBitField.Flags.SendMessages, + PermissionsBitField.Flags.ViewChannel], + }, + { + id: IDs.roles.staff.verifier, + allow: [PermissionsBitField.Flags.SendMessages, + PermissionsBitField.Flags.ViewChannel], + }, + { + id: IDs.roles.staff.trialVerifier, + allow: [PermissionsBitField.Flags.SendMessages, + PermissionsBitField.Flags.ViewChannel], + }, + ], + }); + return channel; +} + +export async function createVerificationVoice( + category: CategoryChannel, + full = false, +) { + const { guild } = category; + + const channel = await guild.channels.create({ + name: 'Verification', + type: ChannelType.GuildVoice, + parent: category.id, + userLimit: 1, + permissionOverwrites: [ + { + id: guild.roles.everyone, + deny: [PermissionsBitField.Flags.SendMessages, + PermissionsBitField.Flags.ViewChannel, + PermissionsBitField.Flags.Stream], + }, + { + id: IDs.roles.verifyBlock, + deny: [PermissionsBitField.Flags.ViewChannel, + PermissionsBitField.Flags.Connect, + PermissionsBitField.Flags.SendMessages], + }, + { + id: IDs.roles.nonvegan.nonvegan, + allow: [PermissionsBitField.Flags.ViewChannel], + }, + { + id: IDs.roles.vegan.vegan, + allow: [PermissionsBitField.Flags.ViewChannel], + }, + { + id: IDs.roles.vegan.activist, + deny: [PermissionsBitField.Flags.ViewChannel, + PermissionsBitField.Flags.Connect], + }, + { + id: IDs.roles.staff.verifier, + allow: [PermissionsBitField.Flags.SendMessages, + PermissionsBitField.Flags.ViewChannel, + PermissionsBitField.Flags.Connect, + PermissionsBitField.Flags.MuteMembers], + }, + { + id: IDs.roles.staff.trialVerifier, + allow: [PermissionsBitField.Flags.SendMessages, + PermissionsBitField.Flags.ViewChannel, + PermissionsBitField.Flags.Connect, + PermissionsBitField.Flags.MuteMembers], + }, + ], + }); + + if (full) { + await channel.permissionOverwrites.edit(IDs.roles.nonvegan.nonvegan, { Connect: false }); + await channel.permissionOverwrites.edit(IDs.roles.vegan.vegan, { Connect: false }); + } +} From 946b8e4440acd2ea91840679c50e9b2a370c7166 Mon Sep 17 00:00:00 2001 From: smyalygames Date: Sat, 18 Feb 2023 15:25:23 +0000 Subject: [PATCH 04/13] feat(arabot): enable give roles back on join --- src/listeners/rolesJoinServer.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/listeners/rolesJoinServer.ts b/src/listeners/rolesJoinServer.ts index a4e7216..0c2871c 100644 --- a/src/listeners/rolesJoinServer.ts +++ b/src/listeners/rolesJoinServer.ts @@ -19,7 +19,7 @@ import { Listener } from '@sapphire/framework'; import type { GuildMember } from 'discord.js'; -// import { fetchRoles } from '#utils/database/dbExistingUser'; +import { fetchRoles } from '#utils/database/dbExistingUser'; import IDs from '#utils/ids'; import { blockTime } from '#utils/database/verification'; import { checkActive, getSection } from '#utils/database/restriction'; @@ -35,8 +35,7 @@ export class RolesJoinServerListener extends Listener { public async run(member: GuildMember) { // Add basic roles - const roles = []; - // const roles = await fetchRoles(member.id); + const roles = await fetchRoles(member.id); // Check if the user is restricted if (await checkActive(member.id)) { From f8a120b1359ecc719c183bf2d5d11902896cf2cb Mon Sep 17 00:00:00 2001 From: smyalygames Date: Sun, 19 Feb 2023 13:35:01 +0000 Subject: [PATCH 05/13] refactor(arabot): change wording --- src/listeners/nonVeganAccess.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/listeners/nonVeganAccess.ts b/src/listeners/nonVeganAccess.ts index 89243f4..f005e1f 100644 --- a/src/listeners/nonVeganAccess.ts +++ b/src/listeners/nonVeganAccess.ts @@ -51,15 +51,16 @@ export class NonVeganAccessReady extends Listener { const messages = await roles.messages.fetch(); const message = messages.first(); - const content = 'If you\'re vegan want your access removed/added back to the non vegan sections' - + 'press the button bellow to gain/remove access to the non vegan sections.'; + const content = '**Change access to non-vegan section of the server:**\n\n' + + 'If you\'re vegan and want your access removed/added back to the non vegan sections, ' + + 'press the button bellow to remove/gain access to the non vegan sections.'; const button = new ActionRowBuilder() .addComponents( new ButtonBuilder() .setCustomId('nvAccess') .setLabel('Non Vegan Access') - .setStyle(ButtonStyle.Secondary), + .setStyle(ButtonStyle.Primary), ); if (message?.author.id !== botId) { From a7c2541d8945d0d61b5a70c6fff6a3afb0370708 Mon Sep 17 00:00:00 2001 From: smyalygames Date: Sun, 19 Feb 2023 13:35:18 +0000 Subject: [PATCH 06/13] feat(arabot): change role for non vegan access --- src/interaction-handlers/nonVeganAccess.ts | 12 ++++++------ src/utils/devIDs.ts | 1 + src/utils/ids.ts | 1 + 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/interaction-handlers/nonVeganAccess.ts b/src/interaction-handlers/nonVeganAccess.ts index 5160d43..871c2d3 100644 --- a/src/interaction-handlers/nonVeganAccess.ts +++ b/src/interaction-handlers/nonVeganAccess.ts @@ -38,7 +38,7 @@ export class NonVeganAccessButtonHandler extends InteractionHandler { public async run(interaction: ButtonInteraction) { let { member } = interaction; - const errorMessage = 'There was an error giving you the role, please try again later or contact ModMail/the developer' + const errorMessage = 'There was an error giving you the role, please try again later or contact ModMail/the developer ' + 'to sort out this problem.'; if (member === null) { @@ -60,19 +60,19 @@ export class NonVeganAccessButtonHandler extends InteractionHandler { return; } - if (member.roles.cache.has(IDs.roles.vegan.activist)) { - await member.roles.remove(IDs.roles.vegan.activist); + if (member.roles.cache.has(IDs.roles.vegan.nvAccess)) { + await member.roles.remove(IDs.roles.vegan.nvAccess); await interaction.reply({ - content: 'Your access from the non vegan section has been removed successfully. ' + content: 'Your access from the non vegan section has been removed. ' + 'If you want to gain access again, click this button again.', ephemeral: true, }); return; } - await member.roles.add(IDs.roles.vegan.activist); + await member.roles.add(IDs.roles.vegan.nvAccess); await interaction.reply({ - content: 'Your access to the non vegan section has been given back successfully. ' + content: 'Your access to the non vegan section has been given back. ' + 'If you want to remove access again, click this button again.', ephemeral: true, }); diff --git a/src/utils/devIDs.ts b/src/utils/devIDs.ts index f8e2fb4..b89f977 100644 --- a/src/utils/devIDs.ts +++ b/src/utils/devIDs.ts @@ -28,6 +28,7 @@ const devIDs = { vegan: { vegan: '999431675098447937', activist: '999431675098447934', + nvAccess: '1076859125415301141', plus: '999431675010359460', }, restrictions: { diff --git a/src/utils/ids.ts b/src/utils/ids.ts index e09e7d2..c69c51b 100644 --- a/src/utils/ids.ts +++ b/src/utils/ids.ts @@ -31,6 +31,7 @@ let IDs = { vegan: { vegan: '788114978020392982', activist: '730915638746546257', + nvAccess: '1076857105648209971', plus: '798682625619132428', }, restrictions: { From 6979a0e79c51b4d63c1866d7ac7b64e96d33a4ba Mon Sep 17 00:00:00 2001 From: smyalygames Date: Sun, 19 Feb 2023 16:34:25 +0000 Subject: [PATCH 07/13] feat(arabot): disable role creation for now --- src/listeners/nonVeganAccess.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/listeners/nonVeganAccess.ts b/src/listeners/nonVeganAccess.ts index f005e1f..afee1da 100644 --- a/src/listeners/nonVeganAccess.ts +++ b/src/listeners/nonVeganAccess.ts @@ -32,6 +32,7 @@ export class NonVeganAccessReady extends Listener { ...options, once: true, event: 'ready', + enabled: false, }); } From c4075fe9f9d35afbd2a2f54c8f59a61125752efd Mon Sep 17 00:00:00 2001 From: smyalygames Date: Sun, 19 Feb 2023 16:34:43 +0000 Subject: [PATCH 08/13] feat(arabot): create custom error for catch --- src/interaction-handlers/nonVeganAccess.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/interaction-handlers/nonVeganAccess.ts b/src/interaction-handlers/nonVeganAccess.ts index 871c2d3..c2e6d4b 100644 --- a/src/interaction-handlers/nonVeganAccess.ts +++ b/src/interaction-handlers/nonVeganAccess.ts @@ -77,6 +77,7 @@ export class NonVeganAccessButtonHandler extends InteractionHandler { ephemeral: true, }); } catch (error) { + this.container.logger.error(`Non Vegan Access Interaction: ${error}`); await interaction.reply({ content: errorMessage, ephemeral: true, From ff6f22005f7dbdc1a72872f7504f9aa0a5c506c8 Mon Sep 17 00:00:00 2001 From: smyalygames Date: Sun, 19 Feb 2023 16:34:54 +0000 Subject: [PATCH 09/13] feat(arabot): create command for nvaccess --- src/commands/roles/nvAccess.ts | 65 ++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/commands/roles/nvAccess.ts diff --git a/src/commands/roles/nvAccess.ts b/src/commands/roles/nvAccess.ts new file mode 100644 index 0000000..5fddacf --- /dev/null +++ b/src/commands/roles/nvAccess.ts @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +/* + Animal Rights Advocates Discord Bot + Copyright (C) 2023 Anthony Berg + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +import { Command } from '@sapphire/framework'; +import type { Message } from 'discord.js'; +import IDs from '#utils/ids'; +import { DurationFormatter } from '@sapphire/time-utilities'; + +export class ActivistCommand extends Command { + public constructor(context: Command.Context, options: Command.Options) { + super(context, { + ...options, + name: 'nvaccess', + description: 'Gives the nvaccess role', + preconditions: ['DevCoordinatorOnly'], + }); + } + + public async messageRun(message: Message) { + const { guild } = message; + + if (guild === null) { + await message.reply('Guild is null'); + await message.react('❌'); + return; + } + await guild.members.fetch(); + + const vegan = await guild.roles.cache.get(IDs.roles.vegan.vegan); + + if (vegan === undefined) { + return; + } + + const vegans = vegan.members.map((member) => member); + const count = vegans.length; + const timeout = 1500; + + await message.reply(`Starting the process now, ETA to completion: ${new DurationFormatter().format(timeout * count)}`); + + for (let i = 0; i < count; i += 1) { + const member = vegans[i]; + setTimeout(async () => { + await member.roles.add(IDs.roles.vegan.nvAccess); + this.container.logger.debug(`NVAccess: Processed ${i + 1}/${count}`); + }, timeout * i); + } + } +} From 9990db84b21460e51f76f48d54704f27ea9b837d Mon Sep 17 00:00:00 2001 From: smyalygames Date: Sun, 19 Feb 2023 20:32:51 +0000 Subject: [PATCH 10/13] fix(arabot): add potential fix for restricted roles --- src/listeners/rolesJoinServer.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/listeners/rolesJoinServer.ts b/src/listeners/rolesJoinServer.ts index 0c2871c..bb77209 100644 --- a/src/listeners/rolesJoinServer.ts +++ b/src/listeners/rolesJoinServer.ts @@ -40,7 +40,9 @@ export class RolesJoinServerListener extends Listener { // Check if the user is restricted if (await checkActive(member.id)) { const section = await getSection(member.id); - roles.length = 0; + for (let i = 0; i < roles.length; i += 1) { + roles.pop(); + } roles.push(IDs.roles.restrictions.restricted[section - 1]); } From dbc359d11bac06bcca3c563176531cba16763bda Mon Sep 17 00:00:00 2001 From: smyalygames Date: Sun, 19 Feb 2023 20:33:30 +0000 Subject: [PATCH 11/13] feat(arabot): add nv access to verifications --- src/listeners/verification/joinVC.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/listeners/verification/joinVC.ts b/src/listeners/verification/joinVC.ts index f504ef6..1af6c45 100644 --- a/src/listeners/verification/joinVC.ts +++ b/src/listeners/verification/joinVC.ts @@ -534,6 +534,7 @@ export class VerificationJoinVCListener extends Listener { } if (roles.vegan) { rolesText += `<@&${IDs.roles.vegan.vegan}>`; + rolesText += `<@&${IDs.roles.vegan.nvAccess}`; } else { rolesText += `<@&${IDs.roles.nonvegan.nonvegan}>`; } @@ -565,6 +566,7 @@ export class VerificationJoinVCListener extends Listener { } if (roles.vegan) { rolesAdd.push(IDs.roles.vegan.vegan); + rolesAdd.push(IDs.roles.vegan.nvAccess); } else { rolesAdd.push(IDs.roles.nonvegan.nonvegan); } From 4bb38415bd89aafca49d4480a7d96c20867abae0 Mon Sep 17 00:00:00 2001 From: smyalygames Date: Sun, 19 Feb 2023 20:33:57 +0000 Subject: [PATCH 12/13] feat(arabot): enable non vegan access for roles --- src/listeners/nonVeganAccess.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/listeners/nonVeganAccess.ts b/src/listeners/nonVeganAccess.ts index afee1da..f005e1f 100644 --- a/src/listeners/nonVeganAccess.ts +++ b/src/listeners/nonVeganAccess.ts @@ -32,7 +32,6 @@ export class NonVeganAccessReady extends Listener { ...options, once: true, event: 'ready', - enabled: false, }); } From 7de8b22e0ecae15b39507b49844dac3365a7ac3b Mon Sep 17 00:00:00 2001 From: smyalygames Date: Sun, 19 Feb 2023 21:27:08 +0000 Subject: [PATCH 13/13] feat(arabot): dealt with nv restrict roles in other commands --- src/commands/mod/restriction/restrict.ts | 1 + src/commands/roles/nvAccess.ts | 65 ------------------------ src/commands/roles/vegan.ts | 6 ++- 3 files changed, 6 insertions(+), 66 deletions(-) delete mode 100644 src/commands/roles/nvAccess.ts diff --git a/src/commands/mod/restriction/restrict.ts b/src/commands/mod/restriction/restrict.ts index cfc3915..3810e8d 100644 --- a/src/commands/mod/restriction/restrict.ts +++ b/src/commands/mod/restriction/restrict.ts @@ -214,6 +214,7 @@ export async function restrictRun( IDs.roles.vegan.vegan, IDs.roles.vegan.plus, IDs.roles.vegan.activist, + IDs.roles.vegan.nvAccess, IDs.roles.trusted, IDs.roles.nonvegan.nonvegan, IDs.roles.nonvegan.convinced, diff --git a/src/commands/roles/nvAccess.ts b/src/commands/roles/nvAccess.ts deleted file mode 100644 index 5fddacf..0000000 --- a/src/commands/roles/nvAccess.ts +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -/* - Animal Rights Advocates Discord Bot - Copyright (C) 2023 Anthony Berg - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ - -import { Command } from '@sapphire/framework'; -import type { Message } from 'discord.js'; -import IDs from '#utils/ids'; -import { DurationFormatter } from '@sapphire/time-utilities'; - -export class ActivistCommand extends Command { - public constructor(context: Command.Context, options: Command.Options) { - super(context, { - ...options, - name: 'nvaccess', - description: 'Gives the nvaccess role', - preconditions: ['DevCoordinatorOnly'], - }); - } - - public async messageRun(message: Message) { - const { guild } = message; - - if (guild === null) { - await message.reply('Guild is null'); - await message.react('❌'); - return; - } - await guild.members.fetch(); - - const vegan = await guild.roles.cache.get(IDs.roles.vegan.vegan); - - if (vegan === undefined) { - return; - } - - const vegans = vegan.members.map((member) => member); - const count = vegans.length; - const timeout = 1500; - - await message.reply(`Starting the process now, ETA to completion: ${new DurationFormatter().format(timeout * count)}`); - - for (let i = 0; i < count; i += 1) { - const member = vegans[i]; - setTimeout(async () => { - await member.roles.add(IDs.roles.vegan.nvAccess); - this.container.logger.debug(`NVAccess: Processed ${i + 1}/${count}`); - }, timeout * i); - } - } -} diff --git a/src/commands/roles/vegan.ts b/src/commands/roles/vegan.ts index 3d26932..a68a3c8 100644 --- a/src/commands/roles/vegan.ts +++ b/src/commands/roles/vegan.ts @@ -103,6 +103,7 @@ export class VeganCommand extends Command { await guildMember.roles.remove([ vegan, IDs.roles.vegan.activist, + IDs.roles.vegan.nvAccess, ]); await interaction.reply({ content: `Removed the ${vegan.name} role from ${user}`, @@ -113,7 +114,10 @@ export class VeganCommand extends Command { } // Add Vegan role to the user - await guildMember.roles.add(vegan); + await guildMember.roles.add([ + vegan, + IDs.roles.vegan.nvAccess, + ]); await guildMember.roles.remove([ IDs.roles.nonvegan.nonvegan, IDs.roles.nonvegan.convinced,