From 20b48e8f42bc508dac26d68b18711b6bfd08bd96 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Sat, 21 Sep 2024 00:11:30 +0000 Subject: [PATCH 01/38] Refactor devcontainer.json and index.js, and update custom-vc.js - Refactor devcontainer.json to forward port 3306 - Refactor index.js to update table creation queries for custom_vc - Refactor custom-vc.js to add and delete ask to join channels for linked channels --- .devcontainer/devcontainer.json | 2 +- index.js | 4 +-- utilities/custom-vc.js | 57 ++++++++++++++++++++++++++++++++- 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 3284284..bbf7085 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -23,7 +23,7 @@ // Use 'forwardPorts' to make a list of ports inside the container available locally. // This can be used to network with other containers or with the host. - // "forwardPorts": [3000, 5432], + "forwardPorts": [3306], // Use 'postCreateCommand' to run commands after the container is created. // "postCreateCommand": "yarn install", diff --git a/index.js b/index.js index cefaa5e..66a8321 100644 --- a/index.js +++ b/index.js @@ -41,7 +41,7 @@ global.client.once('ready', async () => { db = await mariadb.getConnection(); // drop table if it exists // only for testing - // await db.query('DROP TABLE IF EXISTS roles'); + // await db.query('DROP TABLE IF EXISTS custom_vc'); // create roles table if it doesn't exist await db.query('CREATE TABLE IF NOT EXISTS roles (id VARCHAR(255) PRIMARY KEY, emoji VARCHAR(255), raw_emoji VARCHAR(255), message_id VARCHAR(255), channel_id VARCHAR(255)) COLLATE utf8mb4_general_ci CHARSET utf8mb4;'); // create notify table if it doesn't exist @@ -49,7 +49,7 @@ global.client.once('ready', async () => { // create settings table if it doesn't exist await db.query('CREATE TABLE IF NOT EXISTS settings (setting VARCHAR(255) PRIMARY KEY, value BOOLEAN)'); // create custom vc table if it doesn't exist - await db.query('CREATE TABLE IF NOT EXISTS custom_vc (user_id VARCHAR(255) PRIMARY KEY, channel_id VARCHAR(255))'); + await db.query('CREATE TABLE IF NOT EXISTS custom_vc (user_id VARCHAR(255) PRIMARY KEY, channel_id VARCHAR(255), ask_to_join_vc VARCHAR(255))'); // create auto role table if it doesn't exist await db.query('CREATE TABLE IF NOT EXISTS auto_role (role_id VARCHAR(255) PRIMARY KEY)'); // create coda strikes table if it doesn't exist diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index fd9b4bc..c194ffd 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -193,11 +193,13 @@ async function changeVisibility(channelid) { const haspermission = await channel.permissionsFor(guild.roles.everyone).has(PermissionFlagsBits.ViewChannel); if (haspermission) { await channel.permissionOverwrites.edit(guild.roles.everyone.id, { ViewChannel: false, Connect: false }); + await createAskToJoin(channelid); return 'hidden'; } else { await channel.permissionOverwrites.edit(guild.roles.everyone.id, { ViewChannel: true, Connect: true }); // change button to visible + await deleteAskToJoin(channelid); return 'visible'; } } @@ -284,6 +286,7 @@ async function getChannels() { async function deleteChannel(channel_id) { try { const db = await mariadb.getConnection(); + ask_to_join_vc = await db.query('SELECT ask_to_join_vc FROM custom_vc WHERE channel_id = ?', [channel_id]); await db.query('DELETE FROM custom_vc WHERE channel_id = ?', [channel_id]); db.end(); } @@ -295,7 +298,9 @@ async function deleteChannel(channel_id) { if (global.client.channels.cache.get(channel_id)){ await global.client.channels.cache.get(channel_id).delete(); } - + if (ask_to_join_vc[0].ask_to_join_vc) { + await global.client.channels.cache.get(ask_to_join_vc[0].ask_to_join_vc).delete(); + } } catch (error) { console.error(error); @@ -532,4 +537,54 @@ async function setUserCustomVCPermissions(newState, oldState) { } } +async function createAskToJoin(linkedchannel) { + try { + // create an ask to join channel for the linked channel in the ask to join category + const guild = await global.client.guilds.cache.get(env.discord.guild); + const category = await guild.channels.cache.get(env.utilities.customvc.asktojoin); + const linkedchannelobj = await guild.channels.cache.get(linkedchannel); + const channel = await guild.channels.create({ + type: ChannelType.GuildVoice, + name: 'Ask to join ' + linkedchannelobj.name, + parent: category, + permissionOverwrites: [ + { + id: guild.roles.everyone, + deny: [ + PermissionFlagsBits.Connect, + ], + }, + ], + }); + const db = await mariadb.getConnection(); + console.log('created ask to join channel for ' + linkedchannel); + await db.query('UPDATE custom_vc SET ask_to_join_vc = ? WHERE channel_id = ?', [channel.id, linkedchannel]); + db.end(); + return channel; +} +catch (error) { + console.error(error); + embedcreator.sendError(error); +} +} +async function deleteAskToJoin(linkedchannel) { + // delete the ask to join channel for the linked channel + const db = await mariadb.getConnection(); + const rows = await db.query('SELECT ask_to_join_vc FROM custom_vc WHERE channel_id = ?', [linkedchannel]); + db.end(); + try { + if (rows[0].ask_to_join_vc) { + const channel = await global.client.channels.cache.get(rows[0].ask_to_join_vc); + await channel.delete(); + } + const db = await mariadb.getConnection(); + await db.query('UPDATE custom_vc SET ask_to_join_vc = NULL WHERE channel_id = ?', [linkedchannel]); + db.end(); + } + catch (error) { + console.error(error); + embedcreator.sendError(error); +} +} + module.exports = { Create, Cleanup, getChannels, checkUser, deleteChannel, buttonResponder, addUsertoVC, removeUserfromVC, setUserCustomVCPermissions }; \ No newline at end of file From 1046110f717144ccddb06c011f89b4ae93b6d589 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Sat, 21 Sep 2024 21:46:57 +0000 Subject: [PATCH 02/38] Refactor vc-tools.js to set maximum bitrate for voice channels --- utilities/vc-tools.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/vc-tools.js b/utilities/vc-tools.js index 6777875..7b879d2 100644 --- a/utilities/vc-tools.js +++ b/utilities/vc-tools.js @@ -24,7 +24,7 @@ async function setBitrate() { const guild = await global.client.guilds.cache.get(env.discord.guild); const maxbitrate = await getMaxBitrate(); const channels = await guild.channels.cache.filter(channel => channel.type === 2 && channel.bitrate !== maxbitrate); - channels.forEach(async channel => { + await channels.forEach(async channel => { await channel.setBitrate(maxbitrate); bitrate = maxbitrate / 1000; embedcreator.log(`Set bitrate of ${channel} to ${bitrate}kbps`); From 84fdbdb23896af9e6eaa7780b4d2da3cc31339aa Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Sat, 21 Sep 2024 21:47:18 +0000 Subject: [PATCH 03/38] Formatting --- utilities/custom-vc.js | 84 +++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index c194ffd..c32eea5 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -30,7 +30,7 @@ async function buttonResponder(interaction) { await renameChannel(userchannel, newname); followup = await interaction.followUp({ content: 'Channel renamed to ' + newname }); // delete reply after timout - setTimeout(async function() { + setTimeout(async function () { await followup.delete(); const reply = await interaction.fetchReply(); await reply.delete(); @@ -47,7 +47,7 @@ async function buttonResponder(interaction) { if (collected.size === 0) { timeout = await interaction.followUp({ content: 'Timed out' }); // cleanup timeout message - setTimeout(async function() { + setTimeout(async function () { await timeout.delete(); const reply = await interaction.fetchReply(); await reply.delete(); @@ -69,7 +69,7 @@ async function buttonResponder(interaction) { await changeUserLimit(userchannel, newlimit); followup = await interaction.followUp({ content: 'User limit changed to ' + newlimit }); // delete reply after timout - setTimeout(async function() { + setTimeout(async function () { await followup.delete(); const reply = await interaction.fetchReply(); await reply.delete(); @@ -85,21 +85,21 @@ async function buttonResponder(interaction) { else { followup = await interaction.followUp({ content: 'Invalid user limit' }); // delete followUp after timout - setTimeout(async function() { + setTimeout(async function () { await followup.delete(); const reply = await interaction.fetchReply(); await reply.delete(); // delete user message await message.delete(); } - , 1000); + , 1000); } }); collector.on('end', async collected => { if (collected.size === 0) { timeout = await interaction.followUp({ content: 'Timed out' }); // cleanup timeout message - setTimeout(async function() { + setTimeout(async function () { await timeout.delete(); const reply = await interaction.fetchReply(); await reply.delete(); @@ -121,7 +121,7 @@ async function buttonResponder(interaction) { await transferOwnership(userid, newowner.user.id, userchannel); followup = await interaction.followUp({ content: 'Ownership transferred to <@' + newowner.user + '>' }); // delete reply after timout - setTimeout(async function() { + setTimeout(async function () { await followup.delete(); const reply = await interaction.fetchReply(); await reply.delete(); @@ -137,21 +137,21 @@ async function buttonResponder(interaction) { else { followup = await interaction.followUp({ content: 'Invalid user' }); // delete followUp after timout - setTimeout(async function() { + setTimeout(async function () { await followup.delete(); const reply = await interaction.fetchReply(); await reply.delete(); // delete user message await message.delete(); } - , 1000); + , 1000); } }); collector.on('end', async collected => { if (collected.size === 0) { timeout = await interaction.followUp({ content: 'Timed out' }); // cleanup timeout message - setTimeout(async function() { + setTimeout(async function () { await timeout.delete(); const reply = await interaction.fetchReply(); await reply.delete(); @@ -163,7 +163,7 @@ async function buttonResponder(interaction) { const status = await changeVisibility(userchannel); await interaction.reply({ content: 'Visibility changed to ' + status }); // delete reply after timout - setTimeout(async function() { + setTimeout(async function () { const reply = await interaction.fetchReply(); await reply.delete(); }, 1000); @@ -223,7 +223,7 @@ async function changeUserLimit(channelid, newlimit) { // Transfer Ownership async function transferOwnership(olduser, newuser, channelid) { try { - // set vc perms + // set vc perms const channel = await global.client.channels.cache.get(channelid); // set perms await channel.permissionOverwrites.delete(olduser); @@ -295,7 +295,7 @@ async function deleteChannel(channel_id) { embedcreator.sendError(error); } try { - if (global.client.channels.cache.get(channel_id)){ + if (global.client.channels.cache.get(channel_id)) { await global.client.channels.cache.get(channel_id).delete(); } if (ask_to_join_vc[0].ask_to_join_vc) { @@ -456,7 +456,7 @@ async function Cleanup() { if (channel) { // check if channel is empty if (channel.members.size == 0) { - // delete channel + // delete channel await deleteChannel(channel.id); } } @@ -539,33 +539,33 @@ async function setUserCustomVCPermissions(newState, oldState) { async function createAskToJoin(linkedchannel) { try { - // create an ask to join channel for the linked channel in the ask to join category - const guild = await global.client.guilds.cache.get(env.discord.guild); - const category = await guild.channels.cache.get(env.utilities.customvc.asktojoin); - const linkedchannelobj = await guild.channels.cache.get(linkedchannel); - const channel = await guild.channels.create({ - type: ChannelType.GuildVoice, - name: 'Ask to join ' + linkedchannelobj.name, - parent: category, - permissionOverwrites: [ - { - id: guild.roles.everyone, - deny: [ - PermissionFlagsBits.Connect, - ], - }, - ], - }); - const db = await mariadb.getConnection(); - console.log('created ask to join channel for ' + linkedchannel); - await db.query('UPDATE custom_vc SET ask_to_join_vc = ? WHERE channel_id = ?', [channel.id, linkedchannel]); - db.end(); - return channel; -} -catch (error) { - console.error(error); - embedcreator.sendError(error); -} + // create an ask to join channel for the linked channel in the ask to join category + const guild = await global.client.guilds.cache.get(env.discord.guild); + const category = await guild.channels.cache.get(env.utilities.customvc.asktojoin); + const linkedchannelobj = await guild.channels.cache.get(linkedchannel); + const channel = await guild.channels.create({ + type: ChannelType.GuildVoice, + name: 'Ask to join ' + linkedchannelobj.name, + parent: category, + permissionOverwrites: [ + { + id: guild.roles.everyone, + deny: [ + PermissionFlagsBits.Connect, + ], + }, + ], + }); + const db = await mariadb.getConnection(); + console.log('created ask to join channel for ' + linkedchannel); + await db.query('UPDATE custom_vc SET ask_to_join_vc = ? WHERE channel_id = ?', [channel.id, linkedchannel]); + db.end(); + return channel; + } + catch (error) { + console.error(error); + embedcreator.sendError(error); + } } async function deleteAskToJoin(linkedchannel) { // delete the ask to join channel for the linked channel @@ -584,7 +584,7 @@ async function deleteAskToJoin(linkedchannel) { catch (error) { console.error(error); embedcreator.sendError(error); -} + } } module.exports = { Create, Cleanup, getChannels, checkUser, deleteChannel, buttonResponder, addUsertoVC, removeUserfromVC, setUserCustomVCPermissions }; \ No newline at end of file From a53eb9c89a305bbbcfbc6b770a0418ab1488d88e Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Mon, 23 Sep 2024 04:33:59 +0000 Subject: [PATCH 04/38] Refactor voiceStateUpdate function to handle custom voice channels and ask to join channels --- index.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 66a8321..0856850 100644 --- a/index.js +++ b/index.js @@ -252,15 +252,32 @@ global.client.on('messageReactionRemove', async (reaction, user) => { ); global.client.on('voiceStateUpdate', async (oldState, newState) => { + try { + await CustomVC.Cleanup(oldState); + // ensure channel still exists newUserChannel = await newState.channelId; + if (!newUserChannel) return; oldUserChannel = await oldState.channelId; + userid = await newState.member.id; + // get parent category of newState channel const createcustomvc = env.utilities.customvc.channel; - await CustomVC.Cleanup(oldState); + const asktojoin_category = env.utilities.customvc.asktojoin; + const parent = await vctools.getParentChannel(newUserChannel); if (newUserChannel === createcustomvc) { CustomVC.Create(newState); } + if (parent === asktojoin_category) { + console.log('User joined an ask to join channel.'); + CustomVC.askToJoinSendMessage(userid, newUserChannel); + } await vctools.setBitrate(); await CustomVC.setUserCustomVCPermissions(newState, oldState); + } + catch (error) { + console.error(error); + embedcreator.sendError(error); + } + }); // listen for button interactions From d94c8abe9492262c7e028e7ba0966b802b03ceed Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Mon, 23 Sep 2024 04:34:08 +0000 Subject: [PATCH 05/38] Refactor custom-vc.js to improve channel renaming and visibility handling --- utilities/custom-vc.js | 106 +++++++++++++++++++++++++++++++++++------ 1 file changed, 92 insertions(+), 14 deletions(-) diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index c32eea5..1fb585c 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -21,14 +21,14 @@ async function buttonResponder(interaction) { interaction.reply({ content: 'Please enter the new name' }); // message collector to collect new name const filter = m => m.author.id === interaction.user.id; - collector = interaction.channel.createMessageCollector({ filter, time: 600000 }); + collector = await interaction.channel.createMessageCollector({ filter, time: 600000 }); collector.on('collect', async m => { const newname = await m.content; const message = await m; await collector.stop(); collector = false; - await renameChannel(userchannel, newname); - followup = await interaction.followUp({ content: 'Channel renamed to ' + newname }); + const fullnewname = await renameChannel(userchannel, newname); + followup = await interaction.followUp({ content: 'Channel renamed to ' + fullnewname }); // delete reply after timout setTimeout(async function () { await followup.delete(); @@ -59,7 +59,7 @@ async function buttonResponder(interaction) { interaction.reply({ content: 'Please enter the new user limit' }); // message collector to collect new user limit const filter = m => m.author.id === interaction.user.id; - collector = interaction.channel.createMessageCollector({ filter, time: 600000 }); + collector = await interaction.channel.createMessageCollector({ filter, time: 600000 }); collector.on('collect', async m => { const newlimit = await m.content; const message = await m; @@ -178,7 +178,9 @@ async function buttonResponder(interaction) { async function renameChannel(channelid, newname) { try { const channel = await global.client.channels.cache.get(channelid); - return await channel.setName(newname); + const fullnewname = '🔻' + newname; + await channel.setName(fullnewname); + return fullnewname; } catch (error) { console.error(error); @@ -189,7 +191,7 @@ async function renameChannel(channelid, newname) { async function changeVisibility(channelid) { try { guild = await global.client.guilds.cache.get(env.discord.guild); - const channel = global.client.channels.cache.get(channelid); + const channel = await global.client.channels.cache.get(channelid); const haspermission = await channel.permissionsFor(guild.roles.everyone).has(PermissionFlagsBits.ViewChannel); if (haspermission) { await channel.permissionOverwrites.edit(guild.roles.everyone.id, { ViewChannel: false, Connect: false }); @@ -275,11 +277,11 @@ async function checkUser(userid) { async function getChannels() { db = await mariadb.getConnection(); rows = await db.query('SELECT channel_id FROM custom_vc'); - channels = []; - for (row of rows) { + db.end(); + const channels = []; + for (const row of rows) { channels.push(row.channel_id); } - db.end(); return channels; } // Delete Channel @@ -298,7 +300,7 @@ async function deleteChannel(channel_id) { if (global.client.channels.cache.get(channel_id)) { await global.client.channels.cache.get(channel_id).delete(); } - if (ask_to_join_vc[0].ask_to_join_vc) { + if (ask_to_join_vc[0].ask_to_join_vc != null) { await global.client.channels.cache.get(ask_to_join_vc[0].ask_to_join_vc).delete(); } } @@ -325,7 +327,7 @@ async function Create(newState) { nickname = await userobject.displayName; vc_bitrate = await getMaxBitrate(); const channel = await member.guild.channels.create({ - name: nickname + '\'s Channel', + name: '🔻' + nickname + '\'s Channel', type: ChannelType.GuildVoice, bitrate: vc_bitrate, parent: category, @@ -465,6 +467,7 @@ async function Cleanup() { await deleteChannel(channel_id); } } + return 'Custom VC cleanup complete'; } catch (error) { console.error(error); @@ -543,16 +546,21 @@ async function createAskToJoin(linkedchannel) { const guild = await global.client.guilds.cache.get(env.discord.guild); const category = await guild.channels.cache.get(env.utilities.customvc.asktojoin); const linkedchannelobj = await guild.channels.cache.get(linkedchannel); + const strippedname = await linkedchannelobj.name.replace('🔻', ''); const channel = await guild.channels.create({ type: ChannelType.GuildVoice, - name: 'Ask to join ' + linkedchannelobj.name, + name: '🔻Ask to join ' + strippedname, + bitrate: linkedchannelobj.bitrate, parent: category, permissionOverwrites: [ { id: guild.roles.everyone, - deny: [ + allow: [ PermissionFlagsBits.Connect, ], + deny: [ + PermissionFlagsBits.Speak, + ], }, ], }); @@ -586,5 +594,75 @@ async function deleteAskToJoin(linkedchannel) { embedcreator.sendError(error); } } +async function askToJoinSendMessage(userid, linkedchannel) { + try { + const db = await mariadb.getConnection(); + const rows = await db.query('SELECT channel_id from custom_vc WHERE ask_to_join_vc = ?', [linkedchannel]); + // get user from userid + db.end(); + if (rows[0].channel_id) { + const channel = await global.client.channels.cache.get(rows[0].channel_id); + const channel_owner = await db.query('SELECT user_id FROM custom_vc WHERE ask_to_join_vc = ?', [linkedchannel]).then(rows => rows[0].user_id); + const guild = await global.client.guilds.cache.get(env.discord.guild); + const usertomove = await guild.members.fetch(userid); + const custom_vc = await db.query('SELECT channel_id FROM custom_vc WHERE user_id = ?', [channel_owner]).then(rows => rows[0].channel_id); + buttonyes = new ButtonBuilder() + .setCustomId('yes') + .setLabel('Yes') + .setStyle(ButtonStyle.Success) + .setEmoji('✅'); + buttonno = new ButtonBuilder() + .setCustomId('no') + .setLabel('No') + .setStyle(ButtonStyle.Danger) + .setEmoji('❌'); + message = await channel.send({ + content: 'Hey <@' + channel_owner + '>, <@' + userid + '> would like to join your channel.\nClick the button below to allow them to join.', + components: [new ActionRowBuilder().addComponents(buttonyes, buttonno)] + }); + // message collector + const filter = i => i.user.id === channel_owner; + const collector = message.createMessageComponentCollector({ filter, time: 3600000 }); + collector.on('collect', async i => { + if (i.customId === 'yes') { + try { + await i.reply({ content: 'Moved user to channel', ephemeral: true }); + await usertomove.voice.setChannel(custom_vc); + i.message.delete(); + } + catch (error) { + console.error(error); + embedcreator.sendError(error); + i.followUp({ content: 'Error moving user to channel', ephemeral: true }); + } + } + if (i.customId === 'no') { + try { + await i.reply({ content: 'User denied access to channel', ephemeral: true }); + i.message.delete(); + // kick user from channel + await usertomove.voice.setChannel(null); + } + catch (error) { + console.error(error); + embedcreator.sendError(error); + i.followUp({ content: 'Error denying user access to channel', ephemeral: true }); + } + + collector.on('end', async collected => { + if (collected.size === 0) { + message.delete(); + } + }); + } + } + ) + } + } + catch (error) { + console.error(error); + embedcreator.sendError(error); + } +} -module.exports = { Create, Cleanup, getChannels, checkUser, deleteChannel, buttonResponder, addUsertoVC, removeUserfromVC, setUserCustomVCPermissions }; \ No newline at end of file +module.exports = { Create, Cleanup, getChannels, checkUser, deleteChannel, buttonResponder, addUsertoVC, removeUserfromVC, setUserCustomVCPermissions, askToJoinSendMessage }; \ No newline at end of file From 7bc1c4116fd47ae63ccb07d8992f9645bcb46208 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Mon, 23 Sep 2024 04:34:15 +0000 Subject: [PATCH 06/38] Refactor vc-tools.js to add getParentChannel function --- utilities/vc-tools.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/utilities/vc-tools.js b/utilities/vc-tools.js index 7b879d2..db05005 100644 --- a/utilities/vc-tools.js +++ b/utilities/vc-tools.js @@ -35,7 +35,24 @@ async function setBitrate() { embedcreator.sendError(error); } } +async function getParentChannel(channelid) { + try { + const channel = await global.client.channels.cache.get(channelid); + if (channel.parentId) { + return channel.parentId; + } + else { + return null; + } + } + catch (error) { + console.error(error); + embedcreator.sendError(error); + } +} + module.exports = { getMaxBitrate, setBitrate, + getParentChannel }; \ No newline at end of file From d307dfe1b501f1ad140782994ed862231237b382 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Tue, 24 Sep 2024 21:58:30 +0000 Subject: [PATCH 07/38] Create custom_vc_queue table if it doesn't exist --- index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/index.js b/index.js index 0856850..15abddd 100644 --- a/index.js +++ b/index.js @@ -50,6 +50,7 @@ global.client.once('ready', async () => { await db.query('CREATE TABLE IF NOT EXISTS settings (setting VARCHAR(255) PRIMARY KEY, value BOOLEAN)'); // create custom vc table if it doesn't exist await db.query('CREATE TABLE IF NOT EXISTS custom_vc (user_id VARCHAR(255) PRIMARY KEY, channel_id VARCHAR(255), ask_to_join_vc VARCHAR(255))'); + await db.query('CREATE TABLE IF NOT EXISTS custom_vc_queue (user_id VARCHAR(255) PRIMARY KEY, channel_id VARCHAR(255), ask_to_join_vc VARCHAR(255), FOREIGN KEY (channel_id) REFERENCES custom_vc(channel_id) ON DELETE CASCADE) '); // create auto role table if it doesn't exist await db.query('CREATE TABLE IF NOT EXISTS auto_role (role_id VARCHAR(255) PRIMARY KEY)'); // create coda strikes table if it doesn't exist From b854555425c38da88e773e5e3c42b010329d13a0 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Thu, 26 Sep 2024 21:04:35 +0000 Subject: [PATCH 08/38] Add custom VC Queue --- index.js | 2 +- utilities/custom-vc.js | 29 +++++++++++++++++++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index 15abddd..f8ae794 100644 --- a/index.js +++ b/index.js @@ -50,7 +50,7 @@ global.client.once('ready', async () => { await db.query('CREATE TABLE IF NOT EXISTS settings (setting VARCHAR(255) PRIMARY KEY, value BOOLEAN)'); // create custom vc table if it doesn't exist await db.query('CREATE TABLE IF NOT EXISTS custom_vc (user_id VARCHAR(255) PRIMARY KEY, channel_id VARCHAR(255), ask_to_join_vc VARCHAR(255))'); - await db.query('CREATE TABLE IF NOT EXISTS custom_vc_queue (user_id VARCHAR(255) PRIMARY KEY, channel_id VARCHAR(255), ask_to_join_vc VARCHAR(255), FOREIGN KEY (channel_id) REFERENCES custom_vc(channel_id) ON DELETE CASCADE) '); + await db.query('CREATE TABLE IF NOT EXISTS custom_vc_queue (user_id VARCHAR(255) PRIMARY KEY, channel_id VARCHAR(255), ask_to_join_vc VARCHAR(255), message_id VARCHAR(255), FOREIGN KEY (channel_id) REFERENCES custom_vc(channel_id) ON DELETE CASCADE)'); // create auto role table if it doesn't exist await db.query('CREATE TABLE IF NOT EXISTS auto_role (role_id VARCHAR(255) PRIMARY KEY)'); // create coda strikes table if it doesn't exist diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index 1fb585c..84a3670 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -598,8 +598,15 @@ async function askToJoinSendMessage(userid, linkedchannel) { try { const db = await mariadb.getConnection(); const rows = await db.query('SELECT channel_id from custom_vc WHERE ask_to_join_vc = ?', [linkedchannel]); - // get user from userid - db.end(); + if (!rows[0].channel_id) { + db.end(); + return; + } + else { + const insert = await db.query('INSERT INTO custom_vc_queue (channel_id, user_id, linked_channel) VALUES (?, ?, ?)', [userid, linkedchannel, rows[0].channel_id]); + // get user from userid + db.end(); + } if (rows[0].channel_id) { const channel = await global.client.channels.cache.get(rows[0].channel_id); const channel_owner = await db.query('SELECT user_id FROM custom_vc WHERE ask_to_join_vc = ?', [linkedchannel]).then(rows => rows[0].user_id); @@ -628,18 +635,19 @@ async function askToJoinSendMessage(userid, linkedchannel) { try { await i.reply({ content: 'Moved user to channel', ephemeral: true }); await usertomove.voice.setChannel(custom_vc); - i.message.delete(); + deleteAskToJoin(userid); } catch (error) { console.error(error); embedcreator.sendError(error); i.followUp({ content: 'Error moving user to channel', ephemeral: true }); + deleteAskToJoin(userid); } } if (i.customId === 'no') { try { await i.reply({ content: 'User denied access to channel', ephemeral: true }); - i.message.delete(); + deleteAskToJoin(userid); // kick user from channel await usertomove.voice.setChannel(null); } @@ -665,4 +673,17 @@ async function askToJoinSendMessage(userid, linkedchannel) { } } +async function deleteAskToJoin(user_id) { + try { + const db = await mariadb.getConnection(); + await db.query('DELETE FROM custom_vc_queue WHERE user_id = ?', [user_id]); + db.end(); + } + catch (error) { + console.error(error); + embedcreator.sendError(error); + } + +} + module.exports = { Create, Cleanup, getChannels, checkUser, deleteChannel, buttonResponder, addUsertoVC, removeUserfromVC, setUserCustomVCPermissions, askToJoinSendMessage }; \ No newline at end of file From c1d0fc8990c16e6a9ff7e193cbd9504129b49a00 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Fri, 27 Sep 2024 00:10:36 +0000 Subject: [PATCH 09/38] Refactor askToJoinSendMessage function to add message deletion and queue insertion --- utilities/custom-vc.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index 84a3670..df7fc87 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -598,15 +598,6 @@ async function askToJoinSendMessage(userid, linkedchannel) { try { const db = await mariadb.getConnection(); const rows = await db.query('SELECT channel_id from custom_vc WHERE ask_to_join_vc = ?', [linkedchannel]); - if (!rows[0].channel_id) { - db.end(); - return; - } - else { - const insert = await db.query('INSERT INTO custom_vc_queue (channel_id, user_id, linked_channel) VALUES (?, ?, ?)', [userid, linkedchannel, rows[0].channel_id]); - // get user from userid - db.end(); - } if (rows[0].channel_id) { const channel = await global.client.channels.cache.get(rows[0].channel_id); const channel_owner = await db.query('SELECT user_id FROM custom_vc WHERE ask_to_join_vc = ?', [linkedchannel]).then(rows => rows[0].user_id); @@ -627,6 +618,7 @@ async function askToJoinSendMessage(userid, linkedchannel) { content: 'Hey <@' + channel_owner + '>, <@' + userid + '> would like to join your channel.\nClick the button below to allow them to join.', components: [new ActionRowBuilder().addComponents(buttonyes, buttonno)] }); + await db.query('INSERT INTO custom_vc_queue (channel_id, user_id, ask_to_join_vc, message_id) VALUES (?, ?, ?, ?)', [custom_vc, userid, linkedchannel, message.id]); // message collector const filter = i => i.user.id === channel_owner; const collector = message.createMessageComponentCollector({ filter, time: 3600000 }); @@ -676,7 +668,14 @@ async function askToJoinSendMessage(userid, linkedchannel) { async function deleteAskToJoin(user_id) { try { const db = await mariadb.getConnection(); + // get message id + const message_id = await db.query('SELECT message_id, channel_id FROM custom_vc_queue WHERE user_id = ?', [user_id]); + // delete from db await db.query('DELETE FROM custom_vc_queue WHERE user_id = ?', [user_id]); + // delete message + const channel = await global.client.channels.cache.get(message_id[0].channel_id); + const message = await channel.messages.fetch(message_id[0].message_id); + await message.delete(); db.end(); } catch (error) { From f98ab66f792d316fb8e6c7c85916d73c871b7689 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Fri, 27 Sep 2024 00:10:42 +0000 Subject: [PATCH 10/38] Refactor custom_vc table creation query --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index f8ae794..9d5e4d9 100644 --- a/index.js +++ b/index.js @@ -49,7 +49,7 @@ global.client.once('ready', async () => { // create settings table if it doesn't exist await db.query('CREATE TABLE IF NOT EXISTS settings (setting VARCHAR(255) PRIMARY KEY, value BOOLEAN)'); // create custom vc table if it doesn't exist - await db.query('CREATE TABLE IF NOT EXISTS custom_vc (user_id VARCHAR(255) PRIMARY KEY, channel_id VARCHAR(255), ask_to_join_vc VARCHAR(255))'); + await db.query('CREATE TABLE IF NOT EXISTS custom_vc (user_id VARCHAR(255), channel_id VARCHAR(255) PRIMARY KEY, ask_to_join_vc VARCHAR(255))'); await db.query('CREATE TABLE IF NOT EXISTS custom_vc_queue (user_id VARCHAR(255) PRIMARY KEY, channel_id VARCHAR(255), ask_to_join_vc VARCHAR(255), message_id VARCHAR(255), FOREIGN KEY (channel_id) REFERENCES custom_vc(channel_id) ON DELETE CASCADE)'); // create auto role table if it doesn't exist await db.query('CREATE TABLE IF NOT EXISTS auto_role (role_id VARCHAR(255) PRIMARY KEY)'); From 89bd4067b7e7fe3d786946eae21111d59c86bb59 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Fri, 27 Sep 2024 00:12:26 +0000 Subject: [PATCH 11/38] =?UTF-8?q?Refactor=20askToJoinSendMessage=20functio?= =?UTF-8?q?n=20to=20update=20"No"=20button=20emoji=20to=20=E2=9C=96?= =?UTF-8?q?=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utilities/custom-vc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index df7fc87..0c39a3c 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -613,7 +613,7 @@ async function askToJoinSendMessage(userid, linkedchannel) { .setCustomId('no') .setLabel('No') .setStyle(ButtonStyle.Danger) - .setEmoji('❌'); + .setEmoji('✖️'); message = await channel.send({ content: 'Hey <@' + channel_owner + '>, <@' + userid + '> would like to join your channel.\nClick the button below to allow them to join.', components: [new ActionRowBuilder().addComponents(buttonyes, buttonno)] From 6baca21670e5b3432ad6961706bf0a2b7edd5310 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Mon, 30 Sep 2024 00:25:22 +0000 Subject: [PATCH 12/38] =?UTF-8?q?Refactor=20askToJoinSendMessage=20functio?= =?UTF-8?q?n=20to=20update=20"No"=20button=20emoji=20to=20=E2=9C=94?= =?UTF-8?q?=EF=B8=8F=20and=20add=20message=20deletion=20and=20queue=20inse?= =?UTF-8?q?rtion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utilities/custom-vc.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index 0c39a3c..75cd6bc 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -608,7 +608,7 @@ async function askToJoinSendMessage(userid, linkedchannel) { .setCustomId('yes') .setLabel('Yes') .setStyle(ButtonStyle.Success) - .setEmoji('✅'); + .setEmoji('✔️'); buttonno = new ButtonBuilder() .setCustomId('no') .setLabel('No') @@ -621,7 +621,7 @@ async function askToJoinSendMessage(userid, linkedchannel) { await db.query('INSERT INTO custom_vc_queue (channel_id, user_id, ask_to_join_vc, message_id) VALUES (?, ?, ?, ?)', [custom_vc, userid, linkedchannel, message.id]); // message collector const filter = i => i.user.id === channel_owner; - const collector = message.createMessageComponentCollector({ filter, time: 3600000 }); + const collector = await message.createMessageComponentCollector({ filter, time: 3600000 }); collector.on('collect', async i => { if (i.customId === 'yes') { try { From f72161200aa2057fa12c91476bf6be1781044414 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Mon, 30 Sep 2024 01:23:50 +0000 Subject: [PATCH 13/38] Refactor eslint configuration files --- .eslintrc.json | 48 -------------------------- eslint.config.cjs | 87 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 48 deletions(-) delete mode 100644 .eslintrc.json create mode 100644 eslint.config.cjs diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index f9bccb1..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "extends": "eslint:recommended", - "env": { - "node": true, - "es6": true - }, - "parserOptions": { - "ecmaVersion": 2021 - }, - "rules": { - "arrow-spacing": ["warn", { "before": true, "after": true }], - "brace-style": ["error", "stroustrup", { "allowSingleLine": true }], - "comma-dangle": ["error", "always-multiline"], - "comma-spacing": "error", - "comma-style": "error", - "curly": ["error", "multi-line", "consistent"], - "dot-location": ["error", "property"], - "handle-callback-err": "off", - "indent": ["error", "tab"], - "keyword-spacing": "error", - "max-nested-callbacks": ["error", { "max": 4 }], - "max-statements-per-line": ["error", { "max": 2 }], - "no-console": "off", - "no-empty-function": "error", - "no-floating-decimal": "error", - "no-inline-comments": "error", - "no-lonely-if": "error", - "no-multi-spaces": "error", - "no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }], - "no-shadow": ["error", { "allow": ["err", "resolve", "reject", "msg"] }], - "no-trailing-spaces": ["error"], - "no-undef": "off", - "object-curly-spacing": ["error", "always"], - "prefer-const": "error", - "quotes": ["error", "single"], - "semi": ["error", "always"], - "space-before-function-paren": ["error", { - "anonymous": "never", - "named": "never", - "asyncArrow": "always" - }], - "space-in-parens": "error", - "space-infix-ops": "error", - "space-unary-ops": "error", - "spaced-comment": "error", - "yoda": "error" - } -} \ No newline at end of file diff --git a/eslint.config.cjs b/eslint.config.cjs new file mode 100644 index 0000000..43b5c3f --- /dev/null +++ b/eslint.config.cjs @@ -0,0 +1,87 @@ +const globals = require('globals'); +const js = require('@eslint/js'); + +const { + FlatCompat, +} = require('@eslint/eslintrc'); + +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all, +}); + +module.exports = [...compat.extends('eslint:recommended'), { + languageOptions: { + globals: { + ...globals.node, + }, + + ecmaVersion: 2021, + sourceType: 'commonjs', + }, + + rules: { + 'arrow-spacing': ['warn', { + before: true, + after: true, + }], + + 'brace-style': ['error', 'stroustrup', { + allowSingleLine: true, + }], + + 'comma-dangle': ['error', 'always-multiline'], + 'comma-spacing': 'error', + 'comma-style': 'error', + curly: ['error', 'multi-line', 'consistent'], + 'dot-location': ['error', 'property'], + 'handle-callback-err': 'off', + indent: ['error', 'tab'], + 'keyword-spacing': 'error', + + 'max-nested-callbacks': ['error', { + max: 4, + }], + + 'max-statements-per-line': ['error', { + max: 2, + }], + + 'no-console': 'off', + 'no-empty-function': 'error', + 'no-floating-decimal': 'error', + 'no-inline-comments': 'error', + 'no-lonely-if': 'error', + 'no-multi-spaces': 'error', + + 'no-multiple-empty-lines': ['error', { + max: 2, + maxEOF: 1, + maxBOF: 0, + }], + + 'no-shadow': ['error', { + allow: ['err', 'resolve', 'reject', 'msg'], + }], + + 'no-trailing-spaces': ['error'], + 'no-undef': 'off', + 'object-curly-spacing': ['error', 'always'], + 'prefer-const': 'error', + quotes: ['error', 'single'], + semi: ['error', 'always'], + + 'space-before-function-paren': ['error', { + anonymous: 'never', + named: 'never', + asyncArrow: 'always', + }], + + 'space-in-parens': 'error', + 'space-infix-ops': 'error', + 'space-unary-ops': 'error', + 'spaced-comment': 'error', + yoda: 'error', + }, +}]; \ No newline at end of file From 3433dbbe2f48dc1070912d57a1edb02c5135cb02 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Mon, 30 Sep 2024 02:16:25 +0000 Subject: [PATCH 14/38] =?UTF-8?q?Refactor=20askToJoinSendMessage=20functio?= =?UTF-8?q?n=20to=20update=20"No"=20button=20emoji=20to=20=E2=9C=96?= =?UTF-8?q?=EF=B8=8F=20and=20add=20message=20deletion=20and=20queue=20inse?= =?UTF-8?q?rtion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utilities/custom-vc.js | 47 +++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index 75cd6bc..b8c2fbf 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -30,7 +30,7 @@ async function buttonResponder(interaction) { const fullnewname = await renameChannel(userchannel, newname); followup = await interaction.followUp({ content: 'Channel renamed to ' + fullnewname }); // delete reply after timout - setTimeout(async function () { + setTimeout(async function() { await followup.delete(); const reply = await interaction.fetchReply(); await reply.delete(); @@ -47,7 +47,7 @@ async function buttonResponder(interaction) { if (collected.size === 0) { timeout = await interaction.followUp({ content: 'Timed out' }); // cleanup timeout message - setTimeout(async function () { + setTimeout(async function() { await timeout.delete(); const reply = await interaction.fetchReply(); await reply.delete(); @@ -69,7 +69,7 @@ async function buttonResponder(interaction) { await changeUserLimit(userchannel, newlimit); followup = await interaction.followUp({ content: 'User limit changed to ' + newlimit }); // delete reply after timout - setTimeout(async function () { + setTimeout(async function() { await followup.delete(); const reply = await interaction.fetchReply(); await reply.delete(); @@ -85,21 +85,21 @@ async function buttonResponder(interaction) { else { followup = await interaction.followUp({ content: 'Invalid user limit' }); // delete followUp after timout - setTimeout(async function () { + setTimeout(async function() { await followup.delete(); const reply = await interaction.fetchReply(); await reply.delete(); // delete user message await message.delete(); } - , 1000); + , 1000); } }); collector.on('end', async collected => { if (collected.size === 0) { timeout = await interaction.followUp({ content: 'Timed out' }); // cleanup timeout message - setTimeout(async function () { + setTimeout(async function() { await timeout.delete(); const reply = await interaction.fetchReply(); await reply.delete(); @@ -121,7 +121,7 @@ async function buttonResponder(interaction) { await transferOwnership(userid, newowner.user.id, userchannel); followup = await interaction.followUp({ content: 'Ownership transferred to <@' + newowner.user + '>' }); // delete reply after timout - setTimeout(async function () { + setTimeout(async function() { await followup.delete(); const reply = await interaction.fetchReply(); await reply.delete(); @@ -137,21 +137,21 @@ async function buttonResponder(interaction) { else { followup = await interaction.followUp({ content: 'Invalid user' }); // delete followUp after timout - setTimeout(async function () { + setTimeout(async function() { await followup.delete(); const reply = await interaction.fetchReply(); await reply.delete(); // delete user message await message.delete(); } - , 1000); + , 1000); } }); collector.on('end', async collected => { if (collected.size === 0) { timeout = await interaction.followUp({ content: 'Timed out' }); // cleanup timeout message - setTimeout(async function () { + setTimeout(async function() { await timeout.delete(); const reply = await interaction.fetchReply(); await reply.delete(); @@ -163,7 +163,7 @@ async function buttonResponder(interaction) { const status = await changeVisibility(userchannel); await interaction.reply({ content: 'Visibility changed to ' + status }); // delete reply after timout - setTimeout(async function () { + setTimeout(async function() { const reply = await interaction.fetchReply(); await reply.delete(); }, 1000); @@ -201,7 +201,7 @@ async function changeVisibility(channelid) { else { await channel.permissionOverwrites.edit(guild.roles.everyone.id, { ViewChannel: true, Connect: true }); // change button to visible - await deleteAskToJoin(channelid); + await deleteAskToJoinChannel(channelid); return 'visible'; } } @@ -575,7 +575,7 @@ async function createAskToJoin(linkedchannel) { embedcreator.sendError(error); } } -async function deleteAskToJoin(linkedchannel) { +async function deleteAskToJoinChannel(linkedchannel) { // delete the ask to join channel for the linked channel const db = await mariadb.getConnection(); const rows = await db.query('SELECT ask_to_join_vc FROM custom_vc WHERE channel_id = ?', [linkedchannel]); @@ -585,8 +585,8 @@ async function deleteAskToJoin(linkedchannel) { const channel = await global.client.channels.cache.get(rows[0].ask_to_join_vc); await channel.delete(); } - const db = await mariadb.getConnection(); - await db.query('UPDATE custom_vc SET ask_to_join_vc = NULL WHERE channel_id = ?', [linkedchannel]); + const db2 = await mariadb.getConnection(); + await db2.query('UPDATE custom_vc SET ask_to_join_vc = NULL WHERE channel_id = ?', [linkedchannel]); db.end(); } catch (error) { @@ -600,10 +600,10 @@ async function askToJoinSendMessage(userid, linkedchannel) { const rows = await db.query('SELECT channel_id from custom_vc WHERE ask_to_join_vc = ?', [linkedchannel]); if (rows[0].channel_id) { const channel = await global.client.channels.cache.get(rows[0].channel_id); - const channel_owner = await db.query('SELECT user_id FROM custom_vc WHERE ask_to_join_vc = ?', [linkedchannel]).then(rows => rows[0].user_id); + const channel_owner = await db.query('SELECT user_id FROM custom_vc WHERE ask_to_join_vc = ?', [linkedchannel]).then(rowsuid => rowsuid[0].user_id); const guild = await global.client.guilds.cache.get(env.discord.guild); const usertomove = await guild.members.fetch(userid); - const custom_vc = await db.query('SELECT channel_id FROM custom_vc WHERE user_id = ?', [channel_owner]).then(rows => rows[0].channel_id); + const custom_vc = await db.query('SELECT channel_id FROM custom_vc WHERE user_id = ?', [channel_owner]).then(rowscid => rowscid[0].channel_id); buttonyes = new ButtonBuilder() .setCustomId('yes') .setLabel('Yes') @@ -616,9 +616,9 @@ async function askToJoinSendMessage(userid, linkedchannel) { .setEmoji('✖️'); message = await channel.send({ content: 'Hey <@' + channel_owner + '>, <@' + userid + '> would like to join your channel.\nClick the button below to allow them to join.', - components: [new ActionRowBuilder().addComponents(buttonyes, buttonno)] + components: [new ActionRowBuilder().addComponents(buttonyes, buttonno)], }); - await db.query('INSERT INTO custom_vc_queue (channel_id, user_id, ask_to_join_vc, message_id) VALUES (?, ?, ?, ?)', [custom_vc, userid, linkedchannel, message.id]); + await db.query('INSERT INTO custom_vc_queue (channel_id, user_id, ask_to_join_vc, message_id) VALUES (?, ?, ?, ?)', [custom_vc, userid, linkedchannel, message.id]); // message collector const filter = i => i.user.id === channel_owner; const collector = await message.createMessageComponentCollector({ filter, time: 3600000 }); @@ -655,8 +655,8 @@ async function askToJoinSendMessage(userid, linkedchannel) { } }); } - } - ) + }, + ); } } catch (error) { @@ -672,6 +672,7 @@ async function deleteAskToJoin(user_id) { const message_id = await db.query('SELECT message_id, channel_id FROM custom_vc_queue WHERE user_id = ?', [user_id]); // delete from db await db.query('DELETE FROM custom_vc_queue WHERE user_id = ?', [user_id]); + console.log(message_id); // delete message const channel = await global.client.channels.cache.get(message_id[0].channel_id); const message = await channel.messages.fetch(message_id[0].message_id); @@ -682,7 +683,7 @@ async function deleteAskToJoin(user_id) { console.error(error); embedcreator.sendError(error); } - + } -module.exports = { Create, Cleanup, getChannels, checkUser, deleteChannel, buttonResponder, addUsertoVC, removeUserfromVC, setUserCustomVCPermissions, askToJoinSendMessage }; \ No newline at end of file +module.exports = { Create, Cleanup, getChannels, checkUser, deleteChannel, buttonResponder, addUsertoVC, removeUserfromVC, setUserCustomVCPermissions, askToJoinSendMessage, deleteAskToJoinChannel }; \ No newline at end of file From 1ab597000d874af61f8874ff7a975175fe75072e Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Mon, 30 Sep 2024 02:16:39 +0000 Subject: [PATCH 15/38] =?UTF-8?q?Refactor=20askToJoinSendMessage=20functio?= =?UTF-8?q?n=20to=20update=20"No"=20button=20emoji=20to=20=E2=9C=96?= =?UTF-8?q?=EF=B8=8F=20and=20add=20message=20deletion=20and=20queue=20inse?= =?UTF-8?q?rtion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.js | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/index.js b/index.js index 9d5e4d9..484e68c 100644 --- a/index.js +++ b/index.js @@ -254,25 +254,25 @@ global.client.on('messageReactionRemove', async (reaction, user) => { global.client.on('voiceStateUpdate', async (oldState, newState) => { try { - await CustomVC.Cleanup(oldState); - // ensure channel still exists - newUserChannel = await newState.channelId; - if (!newUserChannel) return; - oldUserChannel = await oldState.channelId; - userid = await newState.member.id; - // get parent category of newState channel - const createcustomvc = env.utilities.customvc.channel; - const asktojoin_category = env.utilities.customvc.asktojoin; - const parent = await vctools.getParentChannel(newUserChannel); - if (newUserChannel === createcustomvc) { - CustomVC.Create(newState); - } - if (parent === asktojoin_category) { - console.log('User joined an ask to join channel.'); - CustomVC.askToJoinSendMessage(userid, newUserChannel); - } - await vctools.setBitrate(); - await CustomVC.setUserCustomVCPermissions(newState, oldState); + await CustomVC.Cleanup(oldState); + // ensure channel still exists + newUserChannel = await newState.channelId; + if (!newUserChannel) return; + oldUserChannel = await oldState.channelId; + userid = await newState.member.id; + // get parent category of newState channel + const createcustomvc = env.utilities.customvc.channel; + const asktojoin_category = env.utilities.customvc.asktojoin; + const parent = await vctools.getParentChannel(newUserChannel); + if (newUserChannel === createcustomvc) { + CustomVC.Create(newState); + } + if (parent === asktojoin_category) { + console.log('User joined an ask to join channel.'); + CustomVC.askToJoinSendMessage(userid, newUserChannel); + } + await vctools.setBitrate(); + await CustomVC.setUserCustomVCPermissions(newState, oldState); } catch (error) { console.error(error); From 16c580ecf17eec5294a6e4dccf26fe34cc63c810 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Mon, 30 Sep 2024 02:16:44 +0000 Subject: [PATCH 16/38] Refactor eslint configuration files and update dependencies --- package-lock.json | 67 ++++++++++++++++++++++++++++++++++++++--------- package.json | 3 +++ 2 files changed, 58 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index ad2478f..f9e6405 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,10 @@ "openai": "^4.62.1" }, "devDependencies": { + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "^9.11.1", "eslint": "^9.10.0", + "globals": "^15.9.0", "nodemon": "^3.1.7" } }, @@ -217,6 +220,7 @@ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -235,11 +239,25 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@eslint/js": { - "version": "9.10.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz", - "integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==", + "version": "9.11.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.11.1.tgz", + "integrity": "sha512-/qu+TWz8WwPWc7/HcIJKi+c+MOm46GdVaSlTTQcaqaL53+GsoA6MxWp5PtTx48qbSP7ylM1Kn7nhvkugfJvRSA==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -1040,6 +1058,16 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/@eslint/js": { + "version": "9.10.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz", + "integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/eslint/node_modules/eslint-visitor-keys": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", @@ -1292,10 +1320,11 @@ } }, "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "version": "15.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz", + "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -2331,12 +2360,20 @@ "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true + } } }, "@eslint/js": { - "version": "9.10.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz", - "integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==", + "version": "9.11.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.11.1.tgz", + "integrity": "sha512-/qu+TWz8WwPWc7/HcIJKi+c+MOm46GdVaSlTTQcaqaL53+GsoA6MxWp5PtTx48qbSP7ylM1Kn7nhvkugfJvRSA==", "dev": true }, "@eslint/object-schema": { @@ -2958,6 +2995,12 @@ "text-table": "^0.2.0" }, "dependencies": { + "@eslint/js": { + "version": "9.10.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz", + "integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==", + "dev": true + }, "eslint-visitor-keys": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", @@ -3159,9 +3202,9 @@ } }, "globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "version": "15.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz", + "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==", "dev": true }, "has-flag": { diff --git a/package.json b/package.json index 7f5dc6c..c94a7b2 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,10 @@ }, "homepage": "https://github.com/Project-Coda/Coda-Utilities#readme", "devDependencies": { + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "^9.11.1", "eslint": "^9.10.0", + "globals": "^15.9.0", "nodemon": "^3.1.7" }, "dependencies": { From d80b3de6b725234d673d33fc2cd00221e0c4a605 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Mon, 30 Sep 2024 03:26:46 +0000 Subject: [PATCH 17/38] Refactor askToJoinSendMessage function to update "No" button emoji and add message deletion and queue insertion --- utilities/custom-vc.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index b8c2fbf..4b5a728 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -23,8 +23,8 @@ async function buttonResponder(interaction) { const filter = m => m.author.id === interaction.user.id; collector = await interaction.channel.createMessageCollector({ filter, time: 600000 }); collector.on('collect', async m => { - const newname = await m.content; const message = await m; + const newname = await m.content; await collector.stop(); collector = false; const fullnewname = await renameChannel(userchannel, newname); @@ -180,6 +180,13 @@ async function renameChannel(channelid, newname) { const channel = await global.client.channels.cache.get(channelid); const fullnewname = '🔻' + newname; await channel.setName(fullnewname); + const db = await mariadb.getConnection(); + const ask_to_join_channel = await db.query('SELECT ask_to_join_vc FROM custom_vc WHERE channel_id = ?', [channelid]).then(rows => rows[0].ask_to_join_vc); + db.end(); + if (ask_to_join_channel) { + const ask_to_join_channel_obj = await global.client.channels.cache.get(ask_to_join_channel); + await ask_to_join_channel_obj.setName('🔻Ask to join' + fullnewname); + } return fullnewname; } catch (error) { @@ -192,14 +199,14 @@ async function changeVisibility(channelid) { try { guild = await global.client.guilds.cache.get(env.discord.guild); const channel = await global.client.channels.cache.get(channelid); - const haspermission = await channel.permissionsFor(guild.roles.everyone).has(PermissionFlagsBits.ViewChannel); + const haspermission = await channel.permissionsFor(guild.roles.everyone).has(PermissionFlagsBits.Connect); if (haspermission) { - await channel.permissionOverwrites.edit(guild.roles.everyone.id, { ViewChannel: false, Connect: false }); + await channel.permissionOverwrites.edit(guild.roles.everyone.id, { Connect: false }); await createAskToJoin(channelid); return 'hidden'; } else { - await channel.permissionOverwrites.edit(guild.roles.everyone.id, { ViewChannel: true, Connect: true }); + await channel.permissionOverwrites.edit(guild.roles.everyone.id, { Connect: true }); // change button to visible await deleteAskToJoinChannel(channelid); return 'visible'; @@ -395,7 +402,7 @@ async function generateMenuEmbed(channelid) { const channel = await global.client.channels.cache.get(channelid); const guild = await global.client.guilds.cache.get(env.discord.guild); // check if channel is visible - const visible = await channel.permissionsFor(guild.roles.everyone).has(PermissionFlagsBits.ViewChannel); + const visible = await channel.permissionsFor(guild.roles.everyone).has(PermissionFlagsBits.Connect); if (visible) { visibilitystatus = 'Visible'; visibilitybutton = ButtonStyle.Success; @@ -672,12 +679,12 @@ async function deleteAskToJoin(user_id) { const message_id = await db.query('SELECT message_id, channel_id FROM custom_vc_queue WHERE user_id = ?', [user_id]); // delete from db await db.query('DELETE FROM custom_vc_queue WHERE user_id = ?', [user_id]); + db.end(); console.log(message_id); // delete message const channel = await global.client.channels.cache.get(message_id[0].channel_id); const message = await channel.messages.fetch(message_id[0].message_id); await message.delete(); - db.end(); } catch (error) { console.error(error); From e1722e2359ac59f4427e03355c4faf7123272595 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Tue, 1 Oct 2024 03:22:36 +0000 Subject: [PATCH 18/38] Add hide, lock and disable --- utilities/custom-vc.js | 118 +++++++++++++++++++++++++++++++++++------ 1 file changed, 101 insertions(+), 17 deletions(-) diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index 4b5a728..8defe28 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -37,8 +37,8 @@ async function buttonResponder(interaction) { // delete user message await message.delete(); }, 1000); - const { content, embed, row } = await generateMenuEmbed(interaction.channel.id); - await interaction.followUp({ content: content, embeds: [embed], components: [row] }); + const { content, embed, row, row2 } = await generateMenuEmbed(interaction.channel.id); + await interaction.followUp({ content: content, embeds: [embed], components: [row, row2] }); // cleanup old embed const oldembed = await interaction.channel.messages.fetch(interaction.message.id); await oldembed.delete(); @@ -76,8 +76,8 @@ async function buttonResponder(interaction) { // delete user message await message.delete(); }, 1000); - const { content, embed, row } = await generateMenuEmbed(interaction.channel.id); - await interaction.followUp({ content: content, embeds: [embed], components: [row] }); + const { content, embed, row, row2 } = await generateMenuEmbed(interaction.channel.id); + await interaction.followUp({ content: content, embeds: [embed], components: [row, row2] }); // cleanup old embed const oldembed = await interaction.channel.messages.fetch(interaction.message.id); await oldembed.delete(); @@ -128,8 +128,8 @@ async function buttonResponder(interaction) { // delete user message await message.delete(); }, 1000); - const { content, embed, row } = await generateMenuEmbed(interaction.channel.id); - await interaction.followUp({ content: content, embeds: [embed], components: [row] }); + const { content, embed, row, row2 } = await generateMenuEmbed(interaction.channel.id); + await interaction.followUp({ content: content, embeds: [embed], components: [row, row2] }); // cleanup old embed const oldembed = await interaction.channel.messages.fetch(interaction.message.id); await oldembed.delete(); @@ -167,8 +167,8 @@ async function buttonResponder(interaction) { const reply = await interaction.fetchReply(); await reply.delete(); }, 1000); - const { content, embed, row } = await generateMenuEmbed(interaction.channel.id); - await interaction.followUp({ content: content, embeds: [embed], components: [row] }); + const { content, embed, row, row2 } = await generateMenuEmbed(interaction.channel.id); + await interaction.followUp({ content: content, embeds: [embed], components: [row, row2] }); // cleanup old embed const oldembed = await interaction.channel.messages.fetch(interaction.message.id); await oldembed.delete(); @@ -199,14 +199,14 @@ async function changeVisibility(channelid) { try { guild = await global.client.guilds.cache.get(env.discord.guild); const channel = await global.client.channels.cache.get(channelid); - const haspermission = await channel.permissionsFor(guild.roles.everyone).has(PermissionFlagsBits.Connect); + const haspermission = await channel.permissionsFor(guild.roles.everyone).has(PermissionFlagsBits.ViewChannel); if (haspermission) { - await channel.permissionOverwrites.edit(guild.roles.everyone.id, { Connect: false }); + await channel.permissionOverwrites.edit(guild.roles.everyone.id, { ViewChannel: false }); await createAskToJoin(channelid); return 'hidden'; } else { - await channel.permissionOverwrites.edit(guild.roles.everyone.id, { Connect: true }); + await channel.permissionOverwrites.edit(guild.roles.everyone.id, { ViewChannel: true }); // change button to visible await deleteAskToJoinChannel(channelid); return 'visible'; @@ -218,6 +218,27 @@ async function changeVisibility(channelid) { } } +async function toggleChannelLock(channelid) { + try { + const channel = await global.client.channels.cache.get(channelid); + const haspermission = await channel.permissionsFor(guild.roles.everyone).has(PermissionFlagsBits.Connect); + if (haspermission) { + await channel.permissionOverwrites.edit(guild.roles.everyone.id, { Connect: false }); + createAskToJoin(channelid); + return 'locked'; + } + else { + await channel.permissionOverwrites.edit(guild.roles.everyone.id, { Connect: true }); + deleteAskToJoinChannel(channelid); + return 'unlocked'; + } + } + catch (error) { + console.error(error); + embedcreator.sendError(error); + } +} + // Change User Limit async function changeUserLimit(channelid, newlimit) { try { @@ -383,8 +404,8 @@ async function Create(newState) { } try { // send menu embed - const { content, embed, row } = await generateMenuEmbed(channel.id); - await channel.send({ content: content, embeds: [embed], components: [row] }); + const { content, embed, row, row2 } = await generateMenuEmbed(channel.id); + await channel.send({ content: content, embeds: [embed], components: [row, row2] }); } catch (error) { console.error(error); @@ -402,7 +423,7 @@ async function generateMenuEmbed(channelid) { const channel = await global.client.channels.cache.get(channelid); const guild = await global.client.guilds.cache.get(env.discord.guild); // check if channel is visible - const visible = await channel.permissionsFor(guild.roles.everyone).has(PermissionFlagsBits.Connect); + const visible = await channel.permissionsFor(guild.roles.everyone).has(PermissionFlagsBits.ViewChannel); if (visible) { visibilitystatus = 'Visible'; visibilitybutton = ButtonStyle.Success; @@ -411,6 +432,42 @@ async function generateMenuEmbed(channelid) { visibilitystatus = 'Hidden'; visibilitybutton = ButtonStyle.Danger; } + const lockstatus = await channel.permissionsFor(guild.roles.everyone).has(PermissionFlagsBits.Connect); + if (!lockstatus) { + lockstatuslabel = 'Unlock channel'; + lockstatusemoji = '🔓'; + lockstatusbutton = ButtonStyle.Danger; + if (visible) { + lockstatusdisabled = false; + } + else { + lockstatusdisabled = true; + } + } + else { + lockstatuslabel = 'Lock channel'; + lockstatusemoji = '🔒'; + lockstatusbutton = ButtonStyle.Success; + if (visible) { + lockstatusdisabled = false; + } + else { + lockstatusdisabled = true; + } + } + // check if ask to join is enabled + const ask_to_join_vc = await db.query('SELECT ask_to_join_vc FROM custom_vc WHERE channel_id = ?', [channelid]).then(rowsatj => rowsatj[0].ask_to_join_vc); + if (ask_to_join_vc != null) { + asktojoinstatus = 'Disable ask to join'; + asktojoinstatusemoji = '🔇'; + asktojoinstatusbutton = ButtonStyle.Danger; + } + else { + asktojoinstatus = 'Enable ask to join'; + asktojoinstatusemoji = '🗣️'; + asktojoinstatusbutton = ButtonStyle.Success; + } + const embed = await embedcreator.setembed( { title: 'Custom voice channel menu', @@ -449,9 +506,29 @@ async function generateMenuEmbed(channelid) { .setLabel('Rename channel') .setEmoji('📝') .setStyle(ButtonStyle.Primary); - const row = new ActionRowBuilder() - .addComponents(renamechannel, userlimit, visibility, transferownership, deletechannel); - return { content, embed, row }; + + const hide_ask_to_join = new ButtonBuilder() + .setCustomId('hide_ask_to_join') + .setLabel(asktojoinstatus) + .setEmoji(asktojoinstatusemoji) + .setStyle(asktojoinstatusbutton); + + const toggle_lock = new ButtonBuilder() + .setCustomId('toggle_lock') + .setLabel(lockstatuslabel) + .setEmoji(lockstatusemoji) + .setStyle(lockstatusbutton) + .setDisabled(lockstatusdisabled); + + const row = new ActionRowBuilder() + .addComponents(visibility, toggle_lock); + const row2 = new ActionRowBuilder() + .addComponents(renamechannel, userlimit, transferownership, deletechannel); + if (ask_to_join_vc != null) { + row2.addComponents(hide_ask_to_join); + } + return { content, embed, row, row2 }; + } // Destroy CustomVC async function Cleanup() { @@ -549,6 +626,13 @@ async function setUserCustomVCPermissions(newState, oldState) { async function createAskToJoin(linkedchannel) { try { + // ensure ask to join channel doesn't already exist + const dbcheck = await mariadb.getConnection(); + const rows = await dbcheck.query('SELECT ask_to_join_vc FROM custom_vc WHERE channel_id = ?', [linkedchannel]); + dbcheck.end(); + if (rows[0].ask_to_join_vc) { + return; + } // create an ask to join channel for the linked channel in the ask to join category const guild = await global.client.guilds.cache.get(env.discord.guild); const category = await guild.channels.cache.get(env.utilities.customvc.asktojoin); From b94752489189e1c21f26414bf2d3855135f2aeb0 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Tue, 1 Oct 2024 04:20:17 +0000 Subject: [PATCH 19/38] Refactor buttonResponder function to handle toggle_lock and hide_ask_to_join buttons --- utilities/custom-vc.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index 8defe28..7b74914 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -173,6 +173,33 @@ async function buttonResponder(interaction) { const oldembed = await interaction.channel.messages.fetch(interaction.message.id); await oldembed.delete(); } + if (buttonid === 'toggle_lock') { + const status = await toggleChannelLock(userchannel); + await interaction.reply({ content: 'Channel ' + status }); + // delete reply after timout + setTimeout(async function() { + const reply = await interaction.fetchReply(); + await reply.delete(); + }, 1000); + const { content, embed, row, row2 } = await generateMenuEmbed(interaction.channel.id); + await interaction.followUp({ content: content, embeds: [embed], components: [row, row2] }); + // cleanup old embed + const oldembed = await interaction.channel.messages.fetch(interaction.message.id); + await oldembed.delete(); + } + if (buttonid === 'hide_ask_to_join') { + db3 = await mariadb.getConnection(); + const ask_to_join_vc = await db3.query('SELECT ask_to_join_vc FROM custom_vc WHERE channel_id = ?', [userchannel]).then(rows => rows[0].ask_to_join_vc); + db3.end(); + if (ask_to_join_vc) { + await deleteAskToJoinChannel(userchannel); + await interaction.reply({ content: 'Ask to join disabled' }); + } + else { + await createAskToJoin(userchannel); + await interaction.reply({ content: 'Ask to join enabled' }); + } + } } // Rename Channel async function renameChannel(channelid, newname) { From 3067883000949c9b43948a52a37d7fb4bac70db0 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Wed, 2 Oct 2024 02:31:22 +0000 Subject: [PATCH 20/38] change vc perms and fix bugs --- utilities/custom-vc.js | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index 7b74914..ef1a970 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -199,6 +199,16 @@ async function buttonResponder(interaction) { await createAskToJoin(userchannel); await interaction.reply({ content: 'Ask to join enabled' }); } + + setTimeout(async function() { + const reply = await interaction.fetchReply(); + await reply.delete(); + }, 1000); + const { content, embed, row, row2 } = await generateMenuEmbed(interaction.channel.id); + await interaction.followUp({ content: content, embeds: [embed], components: [row, row2] }); + // cleanup old embed + const oldembed = await interaction.channel.messages.fetch(interaction.message.id); + await oldembed.delete(); } } // Rename Channel @@ -247,16 +257,17 @@ async function changeVisibility(channelid) { async function toggleChannelLock(channelid) { try { + const guild = await global.client.guilds.cache.get(env.discord.guild); const channel = await global.client.channels.cache.get(channelid); const haspermission = await channel.permissionsFor(guild.roles.everyone).has(PermissionFlagsBits.Connect); if (haspermission) { await channel.permissionOverwrites.edit(guild.roles.everyone.id, { Connect: false }); - createAskToJoin(channelid); + await createAskToJoin(channelid); return 'locked'; } else { await channel.permissionOverwrites.edit(guild.roles.everyone.id, { Connect: true }); - deleteAskToJoinChannel(channelid); + await deleteAskToJoinChannel(channelid); return 'unlocked'; } } @@ -406,12 +417,14 @@ async function Create(newState) { id: newState.guild.roles.everyone, allow: [ PermissionFlagsBits.ViewChannel, - PermissionFlagsBits.Connect, PermissionFlagsBits.Stream, PermissionFlagsBits.ReadMessageHistory, PermissionFlagsBits.SendMessages, PermissionFlagsBits.Speak, ], + deny: [ + PermissionFlagsBits.Connect, + ], }, ], }); @@ -430,6 +443,7 @@ async function Create(newState) { embedcreator.sendError(error); } try { + await createAskToJoin(channel.id); // send menu embed const { content, embed, row, row2 } = await generateMenuEmbed(channel.id); await channel.send({ content: content, embeds: [embed], components: [row, row2] }); @@ -484,7 +498,7 @@ async function generateMenuEmbed(channelid) { } // check if ask to join is enabled const ask_to_join_vc = await db.query('SELECT ask_to_join_vc FROM custom_vc WHERE channel_id = ?', [channelid]).then(rowsatj => rowsatj[0].ask_to_join_vc); - if (ask_to_join_vc != null) { + if (ask_to_join_vc) { asktojoinstatus = 'Disable ask to join'; asktojoinstatusemoji = '🔇'; asktojoinstatusbutton = ButtonStyle.Danger; @@ -547,11 +561,11 @@ async function generateMenuEmbed(channelid) { .setStyle(lockstatusbutton) .setDisabled(lockstatusdisabled); - const row = new ActionRowBuilder() + const row = new ActionRowBuilder() .addComponents(visibility, toggle_lock); const row2 = new ActionRowBuilder() .addComponents(renamechannel, userlimit, transferownership, deletechannel); - if (ask_to_join_vc != null) { + if (ask_to_join_vc || !visible || !lockstatus) { row2.addComponents(hide_ask_to_join); } return { content, embed, row, row2 }; From 4a0597f8e35efbb4e2fb1f7a6d946a1f21b0e3f1 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Wed, 2 Oct 2024 03:59:57 +0000 Subject: [PATCH 21/38] Add cleanupAskToJoinMessage function to delete message and remove user from queue --- index.js | 1 + utilities/custom-vc.js | 21 ++++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 484e68c..2c6fdaa 100644 --- a/index.js +++ b/index.js @@ -260,6 +260,7 @@ global.client.on('voiceStateUpdate', async (oldState, newState) => { if (!newUserChannel) return; oldUserChannel = await oldState.channelId; userid = await newState.member.id; + await CustomVC.cleanupAskToJoinMessage(oldUserChannel, newUserChannel, userid); // get parent category of newState channel const createcustomvc = env.utilities.customvc.channel; const asktojoin_category = env.utilities.customvc.asktojoin; diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index ef1a970..18e042d 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -817,5 +817,24 @@ async function deleteAskToJoin(user_id) { } } +async function cleanupAskToJoinMessage(oldStateID, newStateID, user_id) { + // delete message if user leaves ask to join channel + const db = await mariadb.getConnection(); + const rows = await db.query('SELECT message_id, channel_id, ask_to_join_vc FROM custom_vc_queue WHERE user_id = ?', [user_id]); + db.end(); + if (rows.length === 0) { + console.log('no message to delete'); + return; + } + // check to make sure new channel is not the channel the user is asking to join before deleting message o + if (oldStateID === rows[0].ask_to_join_vc && newStateID !== rows[0].channel_id) { + const channel = await global.client.channels.cache.get(rows[0].channel_id); + const message = await channel.messages.fetch(rows[0].message_id); + await message.delete(); + const db2 = await mariadb.getConnection(); + await db2.query('DELETE FROM custom_vc_queue WHERE user_id = ?', [user_id]); + db2.end(); + } +} -module.exports = { Create, Cleanup, getChannels, checkUser, deleteChannel, buttonResponder, addUsertoVC, removeUserfromVC, setUserCustomVCPermissions, askToJoinSendMessage, deleteAskToJoinChannel }; \ No newline at end of file +module.exports = { Create, Cleanup, getChannels, checkUser, deleteChannel, buttonResponder, addUsertoVC, removeUserfromVC, setUserCustomVCPermissions, askToJoinSendMessage, deleteAskToJoinChannel, cleanupAskToJoinMessage }; \ No newline at end of file From c1e367363601144c206a512720d9337a2585cf94 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Wed, 2 Oct 2024 04:00:41 +0000 Subject: [PATCH 22/38] Improve code comment --- utilities/custom-vc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index 18e042d..cebd855 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -826,7 +826,7 @@ async function cleanupAskToJoinMessage(oldStateID, newStateID, user_id) { console.log('no message to delete'); return; } - // check to make sure new channel is not the channel the user is asking to join before deleting message o + // check if user leaves ask to join channel if (oldStateID === rows[0].ask_to_join_vc && newStateID !== rows[0].channel_id) { const channel = await global.client.channels.cache.get(rows[0].channel_id); const message = await channel.messages.fetch(rows[0].message_id); From 052f4300093e83129d0862bb65b58dd8326d0b9f Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Sat, 5 Oct 2024 03:49:18 +0000 Subject: [PATCH 23/38] Refactor code to add vc-logs utility for updating voice channel logs --- index.js | 7 +++++-- utilities/vc-logs.js | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 utilities/vc-logs.js diff --git a/index.js b/index.js index 2c6fdaa..51d2b9d 100644 --- a/index.js +++ b/index.js @@ -15,6 +15,7 @@ const autorole = require('./utilities/autorole.js'); const vctools = require('./utilities/vc-tools.js'); const { checkMention } = require('./utilities/message-filter.js'); const nodecron = require('node-cron'); +const vclogs = require('./utilities/vc-logs.js'); global.client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMessageReactions, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.DirectMessages, GatewayIntentBits.MessageContent, GatewayIntentBits.GuildModeration], partials: [Partials.Message, Partials.Channel, Partials.Reaction], @@ -38,7 +39,7 @@ global.client.once('ready', async () => { }); (async () => { - db = await mariadb.getConnection(); + const db = await mariadb.getConnection(); // drop table if it exists // only for testing // await db.query('DROP TABLE IF EXISTS custom_vc'); @@ -56,6 +57,7 @@ global.client.once('ready', async () => { // create coda strikes table if it doesn't exist // await db.query('DROP TABLE IF EXISTS coda_strikes'); await db.query('CREATE TABLE IF NOT EXISTS coda_strikes (user_id VARCHAR(255) PRIMARY KEY, strikes INT, timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)'); + await db.query('CREATE TABLE IF NOT EXISTS vc_logs (user_id VARCHAR(255), previous_channel VARCHAR(255), new_channel VARCHAR(255), timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)'); db.end(); } )(); @@ -175,7 +177,7 @@ global.client.on('messageReactionAdd', async (reaction, user) => { console.log(emoji); // query db for role try { - db = await mariadb.getConnection(); + const db = await mariadb.getConnection(); const role = await db.query('SELECT * FROM roles WHERE emoji = ? AND message_id = ?', [emoji, message.id]); db.end(); const roleId = String(role[0].id); @@ -260,6 +262,7 @@ global.client.on('voiceStateUpdate', async (oldState, newState) => { if (!newUserChannel) return; oldUserChannel = await oldState.channelId; userid = await newState.member.id; + await vclogs.updateChannel(userid, oldUserChannel, newUserChannel); await CustomVC.cleanupAskToJoinMessage(oldUserChannel, newUserChannel, userid); // get parent category of newState channel const createcustomvc = env.utilities.customvc.channel; diff --git a/utilities/vc-logs.js b/utilities/vc-logs.js new file mode 100644 index 0000000..9eb0207 --- /dev/null +++ b/utilities/vc-logs.js @@ -0,0 +1,34 @@ +const mariadb = require('../db.js'); +const embedcreator = require('../embed.js'); +async function updateChannel(userid, oldchannel, newchannel) { + try { + const db = await mariadb.getConnection(); + const sql = ` + INSERT INTO vc_logs (user_id, previous_channel, new_channel) + VALUES (?, ?, ?) + ON DUPLICATE KEY UPDATE + previous_channel = VALUES(previous_channel), + new_channel = VALUES(new_channel)`; + await db.query(sql, [userid, oldchannel, newchannel]); + } + catch (err) { + console.error(err); + embedcreator.sendError(err); + } + finally { + if (db) { + db.end() + .then(() => console.log('Database connection ended')) + .catch((err) => { + if (err) { + console.error(err); + embedcreator.sendError(err); + } + }, + ); + } + } +} +module.exports = { + updateChannel, +}; \ No newline at end of file From 575d8db9c40560e5cf4beed0bd9f8bc7639155f6 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Sat, 5 Oct 2024 04:32:28 +0000 Subject: [PATCH 24/38] Refactor code to add primary key constraint for vc_logs table --- index.js | 2 +- utilities/custom-vc.js | 31 +++++++++++++++---------------- utilities/vc-logs.js | 14 +------------- 3 files changed, 17 insertions(+), 30 deletions(-) diff --git a/index.js b/index.js index 51d2b9d..4cfe51b 100644 --- a/index.js +++ b/index.js @@ -57,7 +57,7 @@ global.client.once('ready', async () => { // create coda strikes table if it doesn't exist // await db.query('DROP TABLE IF EXISTS coda_strikes'); await db.query('CREATE TABLE IF NOT EXISTS coda_strikes (user_id VARCHAR(255) PRIMARY KEY, strikes INT, timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)'); - await db.query('CREATE TABLE IF NOT EXISTS vc_logs (user_id VARCHAR(255), previous_channel VARCHAR(255), new_channel VARCHAR(255), timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)'); + await db.query('CREATE TABLE IF NOT EXISTS vc_logs (user_id VARCHAR(255) PRIMARY KEY, previous_channel VARCHAR(255), new_channel VARCHAR(255), timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)'); db.end(); } )(); diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index cebd855..58ff63d 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -219,7 +219,7 @@ async function renameChannel(channelid, newname) { await channel.setName(fullnewname); const db = await mariadb.getConnection(); const ask_to_join_channel = await db.query('SELECT ask_to_join_vc FROM custom_vc WHERE channel_id = ?', [channelid]).then(rows => rows[0].ask_to_join_vc); - db.end(); + await db.end(); if (ask_to_join_channel) { const ask_to_join_channel_obj = await global.client.channels.cache.get(ask_to_join_channel); await ask_to_join_channel_obj.setName('🔻Ask to join' + fullnewname); @@ -320,7 +320,7 @@ async function transferOwnership(olduser, newuser, channelid) { try { const db = await mariadb.getConnection(); await db.query('UPDATE custom_vc SET user_id = ? WHERE channel_id = ?', [newuser, channelid]); - db.end(); + await db.end(); } catch (error) { console.error(error); @@ -331,7 +331,7 @@ async function transferOwnership(olduser, newuser, channelid) { async function checkUser(userid) { const db = await mariadb.getConnection(); const rows = await db.query('SELECT channel_id FROM custom_vc WHERE user_id = ?', [userid]); - db.end(); + await db.end(); if (rows.length > 0) { return rows[0].channel_id; } @@ -342,8 +342,8 @@ async function checkUser(userid) { // Get Channels from DB async function getChannels() { db = await mariadb.getConnection(); - rows = await db.query('SELECT channel_id FROM custom_vc'); - db.end(); + const rows = await db.query('SELECT channel_id FROM custom_vc'); + await db.end(); const channels = []; for (const row of rows) { channels.push(row.channel_id); @@ -356,7 +356,7 @@ async function deleteChannel(channel_id) { const db = await mariadb.getConnection(); ask_to_join_vc = await db.query('SELECT ask_to_join_vc FROM custom_vc WHERE channel_id = ?', [channel_id]); await db.query('DELETE FROM custom_vc WHERE channel_id = ?', [channel_id]); - db.end(); + await db.end(); } catch (error) { console.error(error); @@ -458,7 +458,7 @@ async function generateMenuEmbed(channelid) { // get owner const db = await mariadb.getConnection(); const rows = await db.query('SELECT user_id FROM custom_vc WHERE channel_id = ?', [channelid]); - db.end(); + await db.end(); const owner = rows[0].user_id; const content = 'Welcome <@' + owner + '> to your custom voice channel.'; const channel = await global.client.channels.cache.get(channelid); @@ -670,7 +670,7 @@ async function createAskToJoin(linkedchannel) { // ensure ask to join channel doesn't already exist const dbcheck = await mariadb.getConnection(); const rows = await dbcheck.query('SELECT ask_to_join_vc FROM custom_vc WHERE channel_id = ?', [linkedchannel]); - dbcheck.end(); + await dbcheck.end(); if (rows[0].ask_to_join_vc) { return; } @@ -697,9 +697,8 @@ async function createAskToJoin(linkedchannel) { ], }); const db = await mariadb.getConnection(); - console.log('created ask to join channel for ' + linkedchannel); await db.query('UPDATE custom_vc SET ask_to_join_vc = ? WHERE channel_id = ?', [channel.id, linkedchannel]); - db.end(); + await db.end(); return channel; } catch (error) { @@ -711,7 +710,7 @@ async function deleteAskToJoinChannel(linkedchannel) { // delete the ask to join channel for the linked channel const db = await mariadb.getConnection(); const rows = await db.query('SELECT ask_to_join_vc FROM custom_vc WHERE channel_id = ?', [linkedchannel]); - db.end(); + await db.end(); try { if (rows[0].ask_to_join_vc) { const channel = await global.client.channels.cache.get(rows[0].ask_to_join_vc); @@ -719,7 +718,7 @@ async function deleteAskToJoinChannel(linkedchannel) { } const db2 = await mariadb.getConnection(); await db2.query('UPDATE custom_vc SET ask_to_join_vc = NULL WHERE channel_id = ?', [linkedchannel]); - db.end(); + await db.end(); } catch (error) { console.error(error); @@ -751,6 +750,7 @@ async function askToJoinSendMessage(userid, linkedchannel) { components: [new ActionRowBuilder().addComponents(buttonyes, buttonno)], }); await db.query('INSERT INTO custom_vc_queue (channel_id, user_id, ask_to_join_vc, message_id) VALUES (?, ?, ?, ?)', [custom_vc, userid, linkedchannel, message.id]); + db.end(); // message collector const filter = i => i.user.id === channel_owner; const collector = await message.createMessageComponentCollector({ filter, time: 3600000 }); @@ -804,7 +804,7 @@ async function deleteAskToJoin(user_id) { const message_id = await db.query('SELECT message_id, channel_id FROM custom_vc_queue WHERE user_id = ?', [user_id]); // delete from db await db.query('DELETE FROM custom_vc_queue WHERE user_id = ?', [user_id]); - db.end(); + await db.end(); console.log(message_id); // delete message const channel = await global.client.channels.cache.get(message_id[0].channel_id); @@ -821,9 +821,8 @@ async function cleanupAskToJoinMessage(oldStateID, newStateID, user_id) { // delete message if user leaves ask to join channel const db = await mariadb.getConnection(); const rows = await db.query('SELECT message_id, channel_id, ask_to_join_vc FROM custom_vc_queue WHERE user_id = ?', [user_id]); - db.end(); + await db.end(); if (rows.length === 0) { - console.log('no message to delete'); return; } // check if user leaves ask to join channel @@ -833,7 +832,7 @@ async function cleanupAskToJoinMessage(oldStateID, newStateID, user_id) { await message.delete(); const db2 = await mariadb.getConnection(); await db2.query('DELETE FROM custom_vc_queue WHERE user_id = ?', [user_id]); - db2.end(); + await db2.end(); } } diff --git a/utilities/vc-logs.js b/utilities/vc-logs.js index 9eb0207..fef9ca0 100644 --- a/utilities/vc-logs.js +++ b/utilities/vc-logs.js @@ -10,24 +10,12 @@ async function updateChannel(userid, oldchannel, newchannel) { previous_channel = VALUES(previous_channel), new_channel = VALUES(new_channel)`; await db.query(sql, [userid, oldchannel, newchannel]); + await db.end(); } catch (err) { console.error(err); embedcreator.sendError(err); } - finally { - if (db) { - db.end() - .then(() => console.log('Database connection ended')) - .catch((err) => { - if (err) { - console.error(err); - embedcreator.sendError(err); - } - }, - ); - } - } } module.exports = { updateChannel, From 5da699a150beb05a538817643019f576e7c31122 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Sat, 5 Oct 2024 05:13:36 +0000 Subject: [PATCH 25/38] Refactor code to add vc-logs utility for updating voice channel logs and return user to previous channel --- utilities/custom-vc.js | 42 +++++++++++++++++++++++++++--------------- utilities/vc-logs.js | 1 + utilities/vc-tools.js | 26 ++++++++++++++++++++++++-- 3 files changed, 52 insertions(+), 17 deletions(-) diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index 58ff63d..6c53bcc 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -3,6 +3,7 @@ const mariadb = require('../db.js'); const embedcreator = require('../embed.js'); const env = require('../env.js'); const { getMaxBitrate } = require('./vc-tools.js'); +const vctools = require('./vc-tools.js'); collector = false; async function buttonResponder(interaction) { const buttonid = interaction.customId; @@ -773,7 +774,7 @@ async function askToJoinSendMessage(userid, linkedchannel) { await i.reply({ content: 'User denied access to channel', ephemeral: true }); deleteAskToJoin(userid); // kick user from channel - await usertomove.voice.setChannel(null); + await vctools.returnUserToPreviousChannel(userid); } catch (error) { console.error(error); @@ -818,22 +819,33 @@ async function deleteAskToJoin(user_id) { } async function cleanupAskToJoinMessage(oldStateID, newStateID, user_id) { - // delete message if user leaves ask to join channel - const db = await mariadb.getConnection(); - const rows = await db.query('SELECT message_id, channel_id, ask_to_join_vc FROM custom_vc_queue WHERE user_id = ?', [user_id]); - await db.end(); - if (rows.length === 0) { - return; + try { + // delete message if user leaves ask to join channel + const db = await mariadb.getConnection(); + const rows = await db.query('SELECT message_id, channel_id, ask_to_join_vc FROM custom_vc_queue WHERE user_id = ?', [user_id]); + await db.end(); + if (rows.length === 0) { + return; + } + const message_id = rows[0].message_id; + const channel_id = rows[0].channel_id; + const ask_to_join_vc = rows[0].ask_to_join_vc; + // check if user leaves ask to join channel + if (oldStateID === ask_to_join_vc && newStateID !== channel_id) { + const channel = await global.client.channels.cache.get(channel_id); + const message = await channel.messages.fetch(message_id); + await message.delete(); + const db2 = await mariadb.getConnection(); + await db2.query('DELETE FROM custom_vc_queue WHERE user_id = ?', [user_id]); + await db2.end(); + return; + } } - // check if user leaves ask to join channel - if (oldStateID === rows[0].ask_to_join_vc && newStateID !== rows[0].channel_id) { - const channel = await global.client.channels.cache.get(rows[0].channel_id); - const message = await channel.messages.fetch(rows[0].message_id); - await message.delete(); - const db2 = await mariadb.getConnection(); - await db2.query('DELETE FROM custom_vc_queue WHERE user_id = ?', [user_id]); - await db2.end(); + catch (error) { + console.error(error); + embedcreator.sendError(error); } + } module.exports = { Create, Cleanup, getChannels, checkUser, deleteChannel, buttonResponder, addUsertoVC, removeUserfromVC, setUserCustomVCPermissions, askToJoinSendMessage, deleteAskToJoinChannel, cleanupAskToJoinMessage }; \ No newline at end of file diff --git a/utilities/vc-logs.js b/utilities/vc-logs.js index fef9ca0..f0cc3c4 100644 --- a/utilities/vc-logs.js +++ b/utilities/vc-logs.js @@ -11,6 +11,7 @@ async function updateChannel(userid, oldchannel, newchannel) { new_channel = VALUES(new_channel)`; await db.query(sql, [userid, oldchannel, newchannel]); await db.end(); + return; } catch (err) { console.error(err); diff --git a/utilities/vc-tools.js b/utilities/vc-tools.js index db05005..2af81aa 100644 --- a/utilities/vc-tools.js +++ b/utilities/vc-tools.js @@ -1,5 +1,6 @@ const env = require('../env.js'); const embedcreator = require('../embed.js'); +const mariadb = require('../db.js'); async function getMaxBitrate() { // get max bitrate from discord const guild = await global.client.guilds.cache.get(env.discord.guild); @@ -50,9 +51,30 @@ async function getParentChannel(channelid) { embedcreator.sendError(error); } } - +async function returnUserToPreviousChannel(userid) { + try { + const db = await mariadb.getConnection(); + const sql = 'SELECT previous_channel FROM vc_logs WHERE user_id = ?'; + const previouschannel = await db.query(sql, [userid]).then(result => result[0].previous_channel) || null; + await db.end(); + const guild = await global.client.guilds.cache.get(env.discord.guild); + const member = await guild.members.cache.get(userid); + if (!previouschannel) { + return await member.voice.setChannel(null); + } + else { + const channel = await guild.channels.cache.get(previouschannel); + await member.voice.setChannel(channel); + } + } + catch (error) { + console.error(error); + embedcreator.sendError(error); + } +} module.exports = { getMaxBitrate, setBitrate, - getParentChannel + getParentChannel, + returnUserToPreviousChannel, }; \ No newline at end of file From 867e356c52f65e713506457ba0d7ae9e6a41c7f4 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Sat, 5 Oct 2024 05:13:45 +0000 Subject: [PATCH 26/38] Refactor code to add vc-logs utility for updating voice channel logs and return user to previous channel --- index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/index.js b/index.js index 4cfe51b..447ba31 100644 --- a/index.js +++ b/index.js @@ -259,11 +259,11 @@ global.client.on('voiceStateUpdate', async (oldState, newState) => { await CustomVC.Cleanup(oldState); // ensure channel still exists newUserChannel = await newState.channelId; - if (!newUserChannel) return; oldUserChannel = await oldState.channelId; userid = await newState.member.id; await vclogs.updateChannel(userid, oldUserChannel, newUserChannel); await CustomVC.cleanupAskToJoinMessage(oldUserChannel, newUserChannel, userid); + if (!newUserChannel) return; // get parent category of newState channel const createcustomvc = env.utilities.customvc.channel; const asktojoin_category = env.utilities.customvc.asktojoin; @@ -272,7 +272,6 @@ global.client.on('voiceStateUpdate', async (oldState, newState) => { CustomVC.Create(newState); } if (parent === asktojoin_category) { - console.log('User joined an ask to join channel.'); CustomVC.askToJoinSendMessage(userid, newUserChannel); } await vctools.setBitrate(); From 717f3389f24f14d9f2a441f47a6907f04671a48a Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Sat, 5 Oct 2024 05:34:01 +0000 Subject: [PATCH 27/38] Refactor code to add vc-logs utility for updating voice channel logs and return user to previous channel --- utilities/custom-vc.js | 48 +++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index 6c53bcc..c290e52 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -751,35 +751,63 @@ async function askToJoinSendMessage(userid, linkedchannel) { components: [new ActionRowBuilder().addComponents(buttonyes, buttonno)], }); await db.query('INSERT INTO custom_vc_queue (channel_id, user_id, ask_to_join_vc, message_id) VALUES (?, ?, ?, ?)', [custom_vc, userid, linkedchannel, message.id]); - db.end(); + await db.end(); + // get linked channel + const linkedchannelobj = await guild.channels.cache.get(linkedchannel); // message collector const filter = i => i.user.id === channel_owner; const collector = await message.createMessageComponentCollector({ filter, time: 3600000 }); collector.on('collect', async i => { if (i.customId === 'yes') { try { - await i.reply({ content: 'Moved user to channel', ephemeral: true }); + await i.reply({ content: 'Moved user to channel' }).then(msg => { + setTimeout(function() { + msg.delete(); + }, 1000); + }, + ); await usertomove.voice.setChannel(custom_vc); - deleteAskToJoin(userid); + await deleteAskToJoin(userid); } catch (error) { console.error(error); embedcreator.sendError(error); - i.followUp({ content: 'Error moving user to channel', ephemeral: true }); - deleteAskToJoin(userid); + await i.followUp({ content: 'Error moving user to channel' }).then(msg => { + setTimeout(function() { + msg.delete(); + }, 1000); + }, + ); + await deleteAskToJoin(userid); } } if (i.customId === 'no') { try { - await i.reply({ content: 'User denied access to channel', ephemeral: true }); - deleteAskToJoin(userid); - // kick user from channel - await vctools.returnUserToPreviousChannel(userid); + await i.reply({ content: 'User denied access to channel' }).then(msg => { + setTimeout(function() { + msg.delete(); + }, 1000); + }, + ); + await deleteAskToJoin(userid); + // before kicking user from channel, send them a message in the vc channel + linkedchannelobj.send({ content: '<@' + userid + '> you have been denied access to the VC... you will be moved back to your previous channel in 5 seconds' }).then(msg => { + setTimeout(async function() { + // kick user from channel + await vctools.returnUserToPreviousChannel(userid); + msg.delete(); + }, 5000); + }); } catch (error) { console.error(error); embedcreator.sendError(error); - i.followUp({ content: 'Error denying user access to channel', ephemeral: true }); + i.followUp({ content: 'Error denying user access to channel' }).then(msg => { + setTimeout(function() { + msg.delete(); + }, 1000); + }, + ); } collector.on('end', async collected => { From 9973a0444180ab6ee6201bd1d1b325c9858d3d41 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Sat, 5 Oct 2024 05:37:22 +0000 Subject: [PATCH 28/38] Refactor code to add editor default formatter in VSCode settings --- .vscode/settings.json | 3 +++ utilities/custom-vc.js | 15 ++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..e0f8b81 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.defaultFormatter": "dbaeumer.vscode-eslint" +} \ No newline at end of file diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index c290e52..def5f52 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -791,13 +791,14 @@ async function askToJoinSendMessage(userid, linkedchannel) { ); await deleteAskToJoin(userid); // before kicking user from channel, send them a message in the vc channel - linkedchannelobj.send({ content: '<@' + userid + '> you have been denied access to the VC... you will be moved back to your previous channel in 5 seconds' }).then(msg => { - setTimeout(async function() { - // kick user from channel - await vctools.returnUserToPreviousChannel(userid); - msg.delete(); - }, 5000); - }); + linkedchannelobj.send({ content: '<@' + userid + '> you have been denied access to the VC\nYou will be moved back to your previous channel in 5 seconds' }).then( + msg => { + setTimeout(async function() { + // kick user from channel + await vctools.returnUserToPreviousChannel(userid); + msg.delete(); + }, 5000); + }); } catch (error) { console.error(error); From 6a5db27197d62fee60f0abd6802f7bdd647a0617 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Sun, 6 Oct 2024 04:10:58 +0000 Subject: [PATCH 29/38] Refactor code to handle moving users to custom voice channels and returning them to previous channels --- utilities/custom-vc.js | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index def5f52..73637bc 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -766,18 +766,22 @@ async function askToJoinSendMessage(userid, linkedchannel) { }, 1000); }, ); - await usertomove.voice.setChannel(custom_vc); + if (usertomove.voice.channel.id === linkedchannel) { + await usertomove.voice.setChannel(custom_vc); + } + else { + await i.followUp({ content: 'User is no longer in the ask to join channel' }).then(msg => { + setTimeout(function() { + msg.delete(); + }, 1000); + }, + ); + } await deleteAskToJoin(userid); } catch (error) { console.error(error); embedcreator.sendError(error); - await i.followUp({ content: 'Error moving user to channel' }).then(msg => { - setTimeout(function() { - msg.delete(); - }, 1000); - }, - ); await deleteAskToJoin(userid); } } @@ -791,11 +795,23 @@ async function askToJoinSendMessage(userid, linkedchannel) { ); await deleteAskToJoin(userid); // before kicking user from channel, send them a message in the vc channel - linkedchannelobj.send({ content: '<@' + userid + '> you have been denied access to the VC\nYou will be moved back to your previous channel in 5 seconds' }).then( + await linkedchannelobj.send({ content: '<@' + userid + '> you have been denied access to the VC\nYou will be moved back to your previous channel in 5 seconds' }).then( msg => { setTimeout(async function() { // kick user from channel - await vctools.returnUserToPreviousChannel(userid); + if (usertomove.voice.channel.id === linkedchannel) { + await vctools.returnUserToPreviousChannel(userid); + } + else { + await i.followUp({ content: 'User is no longer in the ask to join channel' }).then( + msg => { + // eslint-disable-next-line max-nested-callbacks + setTimeout(function() { + msg.delete(); + }, 1000); + }, + ); + } msg.delete(); }, 5000); }); @@ -803,12 +819,6 @@ async function askToJoinSendMessage(userid, linkedchannel) { catch (error) { console.error(error); embedcreator.sendError(error); - i.followUp({ content: 'Error denying user access to channel' }).then(msg => { - setTimeout(function() { - msg.delete(); - }, 1000); - }, - ); } collector.on('end', async collected => { From 805e07e921b19aa89168c4ac134c9bb1be2244d6 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Sun, 6 Oct 2024 04:26:19 +0000 Subject: [PATCH 30/38] Refactor code to remove console.log statement in deleteAskToJoin function --- utilities/custom-vc.js | 1 - 1 file changed, 1 deletion(-) diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index 73637bc..593da1e 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -845,7 +845,6 @@ async function deleteAskToJoin(user_id) { // delete from db await db.query('DELETE FROM custom_vc_queue WHERE user_id = ?', [user_id]); await db.end(); - console.log(message_id); // delete message const channel = await global.client.channels.cache.get(message_id[0].channel_id); const message = await channel.messages.fetch(message_id[0].message_id); From cf29ef721b333dea47e7265fb1cbcdd828ab6571 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Sun, 6 Oct 2024 04:34:02 +0000 Subject: [PATCH 31/38] Refactor code to add message sending request to join --- utilities/custom-vc.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/utilities/custom-vc.js b/utilities/custom-vc.js index 593da1e..6311e07 100644 --- a/utilities/custom-vc.js +++ b/utilities/custom-vc.js @@ -754,6 +754,11 @@ async function askToJoinSendMessage(userid, linkedchannel) { await db.end(); // get linked channel const linkedchannelobj = await guild.channels.cache.get(linkedchannel); + linkedchannelobj.send({ content: '<@' + userid + '> your request to join has been sent!' }).then(msg => { + setTimeout(function() { + msg.delete(); + }, 5000); + }); // message collector const filter = i => i.user.id === channel_owner; const collector = await message.createMessageComponentCollector({ filter, time: 3600000 }); From a5810e3d82fa6de619ce048970ddcc993d58e42e Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Sun, 6 Oct 2024 20:45:56 +0000 Subject: [PATCH 32/38] Add awaits --- index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 447ba31..8ea4e6a 100644 --- a/index.js +++ b/index.js @@ -269,13 +269,13 @@ global.client.on('voiceStateUpdate', async (oldState, newState) => { const asktojoin_category = env.utilities.customvc.asktojoin; const parent = await vctools.getParentChannel(newUserChannel); if (newUserChannel === createcustomvc) { - CustomVC.Create(newState); + await CustomVC.Create(newState); } if (parent === asktojoin_category) { - CustomVC.askToJoinSendMessage(userid, newUserChannel); + await CustomVC.askToJoinSendMessage(userid, newUserChannel); } - await vctools.setBitrate(); await CustomVC.setUserCustomVCPermissions(newState, oldState); + await vctools.setBitrate(); } catch (error) { console.error(error); From 7f887a8d5f9172c8dc79ffa183b011c20432e899 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Sun, 6 Oct 2024 21:04:16 +0000 Subject: [PATCH 33/38] Update eslint installation command --- .github/workflows/eslint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/eslint.yaml b/.github/workflows/eslint.yaml index a08e060..4e18ba7 100644 --- a/.github/workflows/eslint.yaml +++ b/.github/workflows/eslint.yaml @@ -9,6 +9,6 @@ jobs: - name: Setup Node.js environment uses: actions/setup-node@v4.0.4 - name: Install eslint - run: npm install -g eslint@8.57.0 + run: npm install -g eslint - name: Run eslint run: eslint --ext .js . From a96bf1c56db4aac9bcffe0f92b95786674ccbaa3 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Sun, 6 Oct 2024 21:25:12 +0000 Subject: [PATCH 34/38] Update eslint installation command --- .github/workflows/eslint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/eslint.yaml b/.github/workflows/eslint.yaml index 4e18ba7..1e87e7f 100644 --- a/.github/workflows/eslint.yaml +++ b/.github/workflows/eslint.yaml @@ -9,6 +9,6 @@ jobs: - name: Setup Node.js environment uses: actions/setup-node@v4.0.4 - name: Install eslint - run: npm install -g eslint + run: npm install -g eslint@9.12.0 - name: Run eslint run: eslint --ext .js . From 7fe5b1d056171b449fe88eb2dd63274aaa910129 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Sun, 6 Oct 2024 21:26:33 +0000 Subject: [PATCH 35/38] Update eslint command to use npx --- .github/workflows/eslint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/eslint.yaml b/.github/workflows/eslint.yaml index 1e87e7f..05da9b1 100644 --- a/.github/workflows/eslint.yaml +++ b/.github/workflows/eslint.yaml @@ -11,4 +11,4 @@ jobs: - name: Install eslint run: npm install -g eslint@9.12.0 - name: Run eslint - run: eslint --ext .js . + run: npx eslint . From a85562c1d2df517d67751701b368253bfad0236f Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Sun, 6 Oct 2024 21:33:35 +0000 Subject: [PATCH 36/38] Update eslint and globals versions --- package-lock.json | 48 ++++++++++++++++------------------------------- package.json | 7 +++---- 2 files changed, 19 insertions(+), 36 deletions(-) diff --git a/package-lock.json b/package-lock.json index f589171..f21e111 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,10 +22,9 @@ "openai": "^4.67.1" }, "devDependencies": { - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "^9.11.1", - "eslint": "^9.10.0", - "globals": "^15.9.0", + "@eslint/js": "^9.12.0", + "eslint": "^9.12.0", + "globals": "^15.10.0", "nodemon": "^3.1.7" } }, @@ -262,9 +261,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.11.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.11.1.tgz", - "integrity": "sha512-/qu+TWz8WwPWc7/HcIJKi+c+MOm46GdVaSlTTQcaqaL53+GsoA6MxWp5PtTx48qbSP7ylM1Kn7nhvkugfJvRSA==", + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.12.0.tgz", + "integrity": "sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA==", "dev": true, "license": "MIT", "engines": { @@ -975,6 +974,7 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.12.0.tgz", "integrity": "sha512-UVIOlTEWxwIopRL1wgSQYdnVDcEvs2wyaO6DGo5mXqe3r16IoCNWkR29iHhyaP4cICWjbgbmFUGAhh0GJRuGZw==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.11.0", @@ -1058,16 +1058,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/@eslint/js": { - "version": "9.10.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz", - "integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, "node_modules/eslint/node_modules/eslint-visitor-keys": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", @@ -1311,9 +1301,9 @@ } }, "node_modules/globals": { - "version": "15.9.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz", - "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==", + "version": "15.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.10.0.tgz", + "integrity": "sha512-tqFIbz83w4Y5TCbtgjZjApohbuh7K9BxGYFm7ifwDR240tvdb7P9x+/9VvUKlmkPoiknoJtanI8UOrqxS3a7lQ==", "dev": true, "license": "MIT", "engines": { @@ -2294,9 +2284,9 @@ } }, "@eslint/js": { - "version": "9.11.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.11.1.tgz", - "integrity": "sha512-/qu+TWz8WwPWc7/HcIJKi+c+MOm46GdVaSlTTQcaqaL53+GsoA6MxWp5PtTx48qbSP7ylM1Kn7nhvkugfJvRSA==", + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.12.0.tgz", + "integrity": "sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA==", "dev": true }, "@eslint/object-schema": { @@ -2915,12 +2905,6 @@ "text-table": "^0.2.0" }, "dependencies": { - "@eslint/js": { - "version": "9.10.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz", - "integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==", - "dev": true - }, "eslint-visitor-keys": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", @@ -3113,9 +3097,9 @@ } }, "globals": { - "version": "15.9.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz", - "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==", + "version": "15.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.10.0.tgz", + "integrity": "sha512-tqFIbz83w4Y5TCbtgjZjApohbuh7K9BxGYFm7ifwDR240tvdb7P9x+/9VvUKlmkPoiknoJtanI8UOrqxS3a7lQ==", "dev": true }, "has-flag": { diff --git a/package.json b/package.json index fed28d6..f0136a6 100644 --- a/package.json +++ b/package.json @@ -18,10 +18,9 @@ }, "homepage": "https://github.com/Project-Coda/Coda-Utilities#readme", "devDependencies": { - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "^9.11.1", - "eslint": "^9.10.0", - "globals": "^15.9.0", + "@eslint/js": "^9.12.0", + "eslint": "^9.12.0", + "globals": "^15.10.0", "nodemon": "^3.1.7" }, "dependencies": { From df08e91bca0915777182169a1bcd7e0bb9fd74e7 Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Sun, 6 Oct 2024 21:36:40 +0000 Subject: [PATCH 37/38] Update eslint installation command --- .github/workflows/eslint.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/eslint.yaml b/.github/workflows/eslint.yaml index 05da9b1..c815885 100644 --- a/.github/workflows/eslint.yaml +++ b/.github/workflows/eslint.yaml @@ -8,7 +8,5 @@ jobs: uses: actions/checkout@v4 - name: Setup Node.js environment uses: actions/setup-node@v4.0.4 - - name: Install eslint - run: npm install -g eslint@9.12.0 - name: Run eslint run: npx eslint . From 1d578665128e39bd9bf69387ed95dc99d49a107c Mon Sep 17 00:00:00 2001 From: ikifar2012 Date: Sun, 6 Oct 2024 21:39:14 +0000 Subject: [PATCH 38/38] Update eslint.yaml to install dev dependencies and use npx for running eslint --- .github/workflows/eslint.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/eslint.yaml b/.github/workflows/eslint.yaml index c815885..256daf8 100644 --- a/.github/workflows/eslint.yaml +++ b/.github/workflows/eslint.yaml @@ -8,5 +8,7 @@ jobs: uses: actions/checkout@v4 - name: Setup Node.js environment uses: actions/setup-node@v4.0.4 + - name: Install dev dependencies + run: npm install --only=dev - name: Run eslint run: npx eslint .