diff --git a/.gitignore b/.gitignore index a4908c9..9799a46 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .env node_modules +To-Do +cookies \ No newline at end of file diff --git a/VoiceStateUpdatesOld.js b/VoiceStateUpdatesOld.js deleted file mode 100644 index 862a129..0000000 --- a/VoiceStateUpdatesOld.js +++ /dev/null @@ -1,50 +0,0 @@ -const { Events, ActivityType } = require('discord.js') -require('dotenv').config() -const { client } = require('./index') -const { RepeatMode } = require('distube') -const delay = ms => new Promise(res => setTimeout(res, ms)); -var usersInTartaros = new Set() -var joined = false -const playlist = `https://www.youtube.com/playlist?list=PLjSh2s1ASTgsSdjCgFbpo18RAYF_dHf46` - -module.exports = { - name: Events.VoiceStateUpdate, - once: false, - async execute(oldUser, newUser) { - const guild = client.guilds.cache.get(newUser.guild.id) - const tartarosChannel = await guild.channels.fetch(process.env.D_TartarosID) - - if (newUser.channelId === tartarosChannel.id && oldUser.channelId != newUser.channelId) { - if (newUser.id === '1152718975529140265') { - console.log('Bot joined Tartaros!') - await newUser.setMute(false) - //await newUser.setSuppress(false) - console.log(newUser) - } - - usersInTartaros.add(newUser.id) - console.log(`${usersInTartaros.size} User(s) in Tartaros`) - - if (!joined) { - joined = true; - await client.distube.voices.join(tartarosChannel) - //console.log(await guild.members.me.edit({ mute: false})) - - await delay(3000) - //await tartarosChannel.guild.members.me.edit({ mute: false }) - - // await client.distube.play(playlist) - // const queue = interaction.client.distube.getQueue(interaction.guild) - // await queue.setRepeatMode('Queue') - // await queue.setVolume(40) - console.log('Unmuted') - } - } - - if (oldUser.channelID === tartarosChannel.id && oldUser.channelID != newUser.channelID) { - usersInTartaros.delete(oldUser.id) - //await client.distube.voices.leave(tartarosChannel) - joined = false - } - } -} \ No newline at end of file diff --git a/buttons/honor/honor_multi_confirm.js b/buttons/honor/honor_multi_confirm.js index 820786d..bb23d6d 100644 --- a/buttons/honor/honor_multi_confirm.js +++ b/buttons/honor/honor_multi_confirm.js @@ -8,10 +8,12 @@ module.exports = { async execute(interaction) { let temp = await interaction.message.embeds[0].description.split(' ') var honor - if (temp[5].slice(2, -2) == 'Honor') { + if (temp[5] === '**Honor**') { honor = 1 - } else { + } else if (temp[5] === '**Dishonor**'){ honor = -1 + } else { + return await interaction.reply({content: "ERROR", ephemeral: true}) } const target = await interaction.message.guild.members.fetch(temp[3].slice(2, -1)) temp = interaction.message.embeds[0].description.split('\r\n') @@ -31,12 +33,12 @@ module.exports = { var newThumbnail if (honor == 1) { - description = `Willst du wirklich <@${target.id}> einen Honor geben?\r\n[Grund: ${reason}]` + description = `Willst du wirklich <@${target.id}> einen **Honor** geben?\r\n[Grund: ${reason}]` newTitle = 'Honor Up!' newDescription = `<@${target.id}> erhält einen Honor!\r\n[Grund: ${reason}]` newThumbnail = "https://cdn.discordapp.com/emojis/748176295535443968.webp" } else { - description = `Willst du wirklich <@${target.id}> einen Dishonor geben?\r\n[Grund: ${reason}]` + description = `Willst du wirklich <@${target.id}> einen **Dishonor** geben?\r\n[Grund: ${reason}]` newTitle = 'Honor Down!' newDescription = `<@${target.id}> erhält einen Dishonor!\r\n[Grund: ${reason}]` newThumbnail = "https://cdn.discordapp.com/emojis/748176295132790786.webp" diff --git a/buttons/quotes/quotes_list_left.js b/buttons/quotes/quotes_list_left.js new file mode 100644 index 0000000..c5be62d --- /dev/null +++ b/buttons/quotes/quotes_list_left.js @@ -0,0 +1,82 @@ +const { EmbedBuilder, UserSelectMenuBuilder, ActionRowBuilder } = require("discord.js") +const { mClient } = require("../..") +require('dotenv').config() +module.exports = { + name: 'quotes_list_left', + description: 'navigate left', + async execute(interaction) { + let oldEmbed = interaction.message.embeds[0].data + if (!oldEmbed.footer) { return interaction.reply({ content: 'Please use a Filter', ephemeral: true }) } + if (oldEmbed.fields && oldEmbed.fields[0].value == 0) { return interaction.reply({ content: 'This User has no Quotes', ephemeral: true }) } + + let userID = interaction.message.embeds[0].data.footer.text.split(' ')[5].slice(2, -1) + const target = await interaction.guild.members.fetch(userID) + if (!target) { return interaction.reply({ content: 'Please use a Filter', ephemeral: true }) } + + const db = mClient.db(process.env.M_DB) + const quotesColl = db.collection('quotes') + const quotes = await quotesColl.find({ by: target.id }).toArray() + + var index = Number((await interaction.message.embeds[0].data.title).split(' ')[2].slice(1)) + if (!index) { index = 0 } + index = index - 2 + if (index < 1) { index = 0 } + + + const found = quotes[index] + + const guild = await interaction.client.guilds.fetch(found.guildID) + const channel = await guild.channels.fetch(found.channelID) + const message = await channel.messages.fetch(found.messageID) + + var msgData = { + content: message.content, + author: await message.author, + reference: await message.reference, + embed: await message.embeds ? 'embed' : null + } // debug + if (msgData.reference) { + let refMessage = await channel.messages.fetch(msgData.reference.messageId) + var refData = { + content: refMessage.content, + author: await refMessage.author, + embed: await refMessage.embeds.length > 0 ? 'embed' : null + } + } + + var description = '' + if (refData) { + description += `> ${refData.author}` + if (refData.embed) { + description += '*an embed / a command* ' + } else { + description += refData.content + } + description += `\r\n↳` + } + let messageLink = `https://discord.com/channels/${found.guildID}/${found.channelID}/${found.messageID}` + description += `${msgData.author} ${msgData.content}\r\n\r\n${messageLink}` + let timestamp = new Date(message.createdTimestamp) + let footer = timestamp.toDateString().toString() + + const embed = new EmbedBuilder() + .setThumbnail(msgData.author.displayAvatarURL()) + .setURL(messageLink) + .setTitle(`- Quote #${index + 1} -`) + .setDescription(description) + .setFooter({ text: (`${footer} #${found.messageID} <@${found.by}>`) }) + const select = new ActionRowBuilder() + .addComponents( + new UserSelectMenuBuilder() + .setCustomId('quotes_list_mentionable') + .setPlaceholder('Filter By User') + ) + + const row = interaction.message.components[1] + await interaction.update({ + embeds: [embed], + components: [select, row] + }) + + } +} \ No newline at end of file diff --git a/buttons/quotes/quotes_list_right.js b/buttons/quotes/quotes_list_right.js new file mode 100644 index 0000000..f7cacce --- /dev/null +++ b/buttons/quotes/quotes_list_right.js @@ -0,0 +1,82 @@ +const { EmbedBuilder, UserSelectMenuBuilder, ActionRowBuilder } = require("discord.js") +const { mClient } = require("../..") +require('dotenv').config() +module.exports = { + name: 'quotes_list_right', + description: 'navigate right', + async execute(interaction) { + let oldEmbed = interaction.message.embeds[0].data + if (!oldEmbed.footer) { return interaction.reply({ content: 'Please use a Filter', ephemeral: true }) } + if (oldEmbed.fields && oldEmbed.fields[0].value == 0) { return interaction.reply({ content: 'This User has no Quotes', ephemeral: true }) } + + let userID = interaction.message.embeds[0].data.footer.text.split(' ')[5].slice(2, -1) + const target = await interaction.guild.members.fetch(userID) + if (!target) { return interaction.reply({ content: 'Please use a Filter', ephemeral: true }) } + + const db = mClient.db(process.env.M_DB) + const quotesColl = db.collection('quotes') + const quotes = await quotesColl.find({ by: target.id }).toArray() + + var index = Number((await interaction.message.embeds[0].data.title).split(' ')[2].slice(1)) + if (!index) { index = 0 } + //if (index >= quotes.length){ return interaction.reply({content: 'Max Quotes Reached', ephemeral: true})} + if (index >= quotes.length) { index-- } + + // will automatically reflect the next index due to how arrays think + + const found = quotes[index] + const guild = await interaction.client.guilds.fetch(found.guildID) + const channel = await guild.channels.fetch(found.channelID) + const message = await channel.messages.fetch(found.messageID) + + var msgData = { + content: message.content, + author: await message.author, + reference: await message.reference, + embed: await message.embeds ? 'embed' : null + } // debug + if (msgData.reference) { + let refMessage = await channel.messages.fetch(msgData.reference.messageId) + var refData = { + content: refMessage.content, + author: await refMessage.author, + embed: await refMessage.embeds.length > 0 ? 'embed' : null + } + } + + var description = '' + if (refData) { + description += `> ${refData.author}` + if (refData.embed) { + description += '*an embed / a command* ' + } else { + description += refData.content + } + description += `\r\n↳` + } + let messageLink = `https://discord.com/channels/${found.guildID}/${found.channelID}/${found.messageID}` + description += `${msgData.author} ${msgData.content}\r\n\r\n${messageLink}` + let timestamp = new Date(message.createdTimestamp) + let footer = timestamp.toDateString().toString() + + const embed = new EmbedBuilder() + .setThumbnail(msgData.author.displayAvatarURL()) + .setURL(messageLink) + .setTitle(`- Quote #${index + 1} -`) + .setDescription(description) + .setFooter({ text: (`${footer} #${found.messageID} <@${found.by}>`) }) + const select = new ActionRowBuilder() + .addComponents( + new UserSelectMenuBuilder() + .setCustomId('quotes_list_mentionable') + .setPlaceholder('Filter By User') + ) + + const row = interaction.message.components[1] + await interaction.update({ + embeds: [embed], + components: [select, row] + }) + + } +} \ No newline at end of file diff --git a/buttons/test/test_button_1.js b/buttons/test/test_button_1.js deleted file mode 100644 index 0e81975..0000000 --- a/buttons/test/test_button_1.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - name: 'test_button_1', - description: 'a test button', - execute(interaction){ - interaction.reply({ - content: 'Success' - }) - } -} \ No newline at end of file diff --git a/commands/honors/honors.js b/commands/honors/honors.js index 2dc6e37..7ac7933 100644 --- a/commands/honors/honors.js +++ b/commands/honors/honors.js @@ -163,7 +163,7 @@ async function honorCheck(interaction) { } async function honorMenu(interaction) { const embed = new EmbedBuilder() - .setTitle('- Honor Menu WIP! -') + .setTitle('- Honor Menu! -') .setDescription('- Choose someone from the Select Menu below\r\n- Choose Honor Dishonor, or History\r\n- Confirm your Selection') .setThumbnail(interaction.guild.iconURL()) const row = new ActionRowBuilder() diff --git a/commands/music/music.js b/commands/music/music.js deleted file mode 100644 index 1632aa3..0000000 --- a/commands/music/music.js +++ /dev/null @@ -1,165 +0,0 @@ -const { SlashCommandBuilder, EmbedBuilder } = require("discord.js"); -const { configDotenv } = require("dotenv"); -configDotenv - -async function musicJoin(interaction) { - const voiceChannel = await interaction.guild.channels.fetch(process.env.D_RealTartarosID) - await interaction.client.distube.voices.join(voiceChannel) - await voiceChannel.guild.members.me.edit({ mute: false }) - await interaction.reply({ - content: `Joined ${voiceChannel}`, - ephemeral: true - }) -} -async function musicLeave(interaction) { - const voiceChannel = await interaction.guild.channels.fetch(process.env.D_RealTartarosID) - await interaction.client.distube.voices.leave(voiceChannel) - await interaction.reply({ - content: `Left ${voiceChannel}`, - ephemeral: true - }) -} -async function musicPlay(interaction) { - const url = await interaction.options.getString('url') - const regex = /^((?:https?:)?\/\/)?((?:www|m)\.)?((?:youtube\.com|youtu.be))(\/(?:[\w\-]+\?v=|embed\/|v\/)?)([\w\-]+)(\S+)?$/gm - const voiceChannel = await interaction.member.voice.channel - - if (!url.match(regex)) { - return await interaction.editReply({ - content: `Invalid URL`, - ephemeral: true - }) - } - await interaction.client.distube.play(voiceChannel, url) - const queue = interaction.client.distube.getQueue(interaction.guild) - const { name, thumbnail } = queue.songs[0] - const embed = new EmbedBuilder() - .setThumbnail(thumbnail) - .setTitle(`Added ${name} to Queue`) - .setURL(url) - await interaction.editReply({ - embeds: [embed] - }) -} -async function musicVolume(interaction) { - const queue = interaction.client.distube.getQueue(interaction.guild) - if (!queue) { - return await interaction.reply({ - content: `There is nothing in the queue right now!`, - ephemeral: true - }) - } - const volume = await interaction.options.getNumber('volume') - queue.setVolume(volume) - await interaction.reply({ - content: `Set Volume to ${volume}%`, - ephemeral: true - }) -} -async function musicQueue(interaction) { - const queue = interaction.client.distube.getQueue(interaction.guild) - if (!queue) { - return await interaction.reply({ - content: `There is nothing in the queue right now!`, - ephemeral: true - }) - } - const songs = queue.songs.map((song, i) => `${i === 0 ? 'Playing:' : `${i}.`} ${song.name} - \`${song.formattedDuration}\``) - .join('\n') - - const embed = new EmbedBuilder() - .setTitle(`Server Queue`) - .setDescription(songs.toString()) - await interaction.reply({ - embeds: [ embed ] - }) -} -async function musicSkip(interaction) { - const queue = interaction.client.distube.getQueue(interaction.guild) - if (!queue) { - return await interaction.reply({ - content: `There is nothing in the queue right now!`, - ephemeral: true - }) - } - try { - const song = await queue.skip() - await interaction.reply({ - content: `Skipped! Now playing:\n${song.name}` - }) - } catch (e) { - await interaction.reply({ - content: e - }) - } -} -module.exports = { - data: new SlashCommandBuilder() - .setName('music') - .setDescription('handles all music related commands') - .addSubcommand(s => - s - .setName('play') - .setDescription('plays music') - .addStringOption(o => o.setName('url').setDescription('youtube url').setRequired(true)) - ).addSubcommand(s => - s - .setName('join') - .setDescription('join default music channel') - ).addSubcommand(s => - s - .setName('leave') - .setDescription('leave default music channel') - ).addSubcommand(s => - s - .setName('volume') - .setDescription('adjust music volume (default: 50%)') - .addNumberOption(o => o.setName('volume').setDescription('choose volume').addChoices( - { name: '100%', value: 100 }, - { name: '90%', value: 90 }, - { name: '80%', value: 80 }, - { name: '70%', value: 70 }, - { name: '60%', value: 60 }, - { name: '50%', value: 50 }, - { name: '40%', value: 40 }, - { name: '30%', value: 30 }, - { name: '20%', value: 20 }, - { name: '10%', value: 10 }, - { name: '0%', value: 0 }, - ).setRequired(true)) - ).addSubcommand(s => - s - .setName('queue') - .setDescription('show current queue') - ).addSubcommand(s => - s - .setName('skip') - .setDescription('skip current song') - ), - async execute(interaction) { - const subcommand = await interaction.options._subcommand - switch (subcommand) { - case 'play': - interaction.deferReply() - musicPlay(interaction) - break; - case 'join': - musicJoin(interaction) - break; - case 'leave': - musicLeave(interaction) - break; - case 'volume': - musicVolume(interaction) - break; - case 'queue': - musicQueue(interaction) - break; - case 'skip': - musicSkip(interaction) - break; - default: - break; - } - } -} \ No newline at end of file diff --git a/commands/quotes/quotes.js b/commands/quotes/quotes.js index 709ca21..32bcdc2 100644 --- a/commands/quotes/quotes.js +++ b/commands/quotes/quotes.js @@ -9,12 +9,22 @@ Random By Year? List? Counter (Leaderboard?) */ -const { SlashCommandBuilder, EmbedBuilder } = require('discord.js') +const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, UserSelectMenuBuilder } = require('discord.js') const { mClient } = require('../..') require('dotenv').config() async function quotesAdd(interaction) { const messageLink = await interaction.options.getString('link') + //regex for message link + const regex = /^https:\/\/discord\.com\/channels\/\d+\/\d+\/\d+$/ + + if (!messageLink.match(regex)) { + return await interaction.editReply({ + content: `Invalid URL`, + ephemeral: true + }) + } + let temp = messageLink.split('/') let messageID = temp[temp.length - 1] let channelID = temp[temp.length - 2] @@ -31,23 +41,29 @@ async function quotesAdd(interaction) { embed: await message.embeds ? 'embed' : null } // debug if (msgData.reference) { - let refMessage = await channel.messages.fetch(msgData.reference.messageId) + let refGuild = await interaction.client.guilds.fetch(msgData.reference.guildId) + let refChannel = await refGuild.channels.fetch(msgData.reference.channelId) + let refMessage = await refChannel.messages.fetch(msgData.reference.messageId) + + var refData = { content: refMessage.content, author: await refMessage.author, - embed: await refMessage.embeds ? 'embed' : null + embed: await refMessage.embeds.length > 0 ? 'embed' : null } } const db = mClient.db(process.env.M_DB) const quotesColl = db.collection('quotes') const found = await quotesColl.findOne({ messageID: messageID }) - if (found) { return await interaction.reply({ content: 'Quote Already in Database', ephemeral: true }) } + if (found) { return await interaction.editReply({ content: 'Quote Already in Database', ephemeral: true }) } await quotesColl.findOneAndUpdate({ messageID: messageID }, { $set: { messageID: messageID, channelID: channelID, - guildID: guildID + guildID: guildID, + by: msgData.author.id, + count: 0 } }, { upsert: true }) @@ -56,6 +72,8 @@ async function quotesAdd(interaction) { description += `> ${refData.author}` if (refData.embed) { description += '*an embed / a command* ' + } else { + description += refData.content } description += `\r\n↳` } @@ -66,22 +84,199 @@ async function quotesAdd(interaction) { const embed = new EmbedBuilder() .setThumbnail(msgData.author.displayAvatarURL()) .setURL(messageLink) - .setTitle(`Quote #${messageID} Added!`) + .setTitle(`- Quote Added! -`) .setDescription(description) - .setFooter({ text: footer}) - await interaction.reply({ embeds: [embed] }) + .setFooter({ text: (footer + ' #' + messageID) }) + await interaction.editReply({ embeds: [embed] }) } async function quotesRemove(interaction) { + const id = await interaction.options.getString('id') + const db = mClient.db(process.env.M_DB) + const quotesColl = db.collection('quotes') + const found = await quotesColl.findOne({ messageID: id }) + if (!found) { return await interaction.reply({ content: 'ID not found!', ephemeral: true }) } + + await quotesColl.deleteOne({ messageID: id }) + + return interaction.reply({ content: 'Quote successfully removed!', ephemeral: true }) } async function quotesSearch(interaction) { + const id = interaction.options.getString("id") + const db = mClient.db(process.env.M_DB) + const quotesColl = db.collection('quotes') + const found = await quotesColl.findOne({ messageID: id }) + if (!found) { return await interaction.reply({ content: 'ID not found!', ephemeral: true }) } + + + const guild = await interaction.client.guilds.fetch(found.guildID) + const channel = await guild.channels.fetch(found.channelID) + const message = await channel.messages.fetch(found.messageID) + + var msgData = { + content: message.content, + author: await message.author, + reference: await message.reference, + embed: await message.embeds ? 'embed' : null + } // debug + + quotesColl.findOneAndUpdate({ + messageID: found.messageID + },{ + $inc: { count: 1} + },{ + upsert: true + }) + + if (msgData.reference) { + let refMessage = await channel.messages.fetch(msgData.reference.messageId) + var refData = { + content: refMessage.content, + author: await refMessage.author, + embed: await refMessage.embeds.length > 0 ? 'embed' : null + } + } + + var description = '' + if (refData) { + description += `> ${refData.author}` + if (refData.embed) { + description += '*an embed / a command* ' + } else { + description += refData.content + } + description += `\r\n↳` + } + let messageLink = `https://discord.com/channels/${found.guildID}/${found.channelID}/${found.messageID}` + description += `${msgData.author} ${msgData.content}\r\n\r\n${messageLink}` + let timestamp = new Date(message.createdTimestamp) + let footer = timestamp.toDateString().toString() + + const embed = new EmbedBuilder() + .setThumbnail(msgData.author.displayAvatarURL()) + .setURL(messageLink) + .setTitle(`- Quote Found! -`) + .setDescription(description) + .setFooter({ text: (footer + ' #' + found.messageID) }) + await interaction.reply({ embeds: [embed] }) } async function quotesRandom(interaction) { + var user = interaction.options.getUser("by") + const db = mClient.db(process.env.M_DB) + const quotesColl = db.collection('quotes') + var rdm + if(user){ + rdm = await quotesColl.aggregate([ + { + $match: { by: user.id}, + },{ + $sample: { size: 1 } + } + ]).toArray() + } else { + rdm = await quotesColl.aggregate([ + { + $sample: { size: 1 } + } + ]).toArray() + } + const found = rdm[0] + if (!found) { return await interaction.reply({ content: 'Database Empty', ephemeral: true }) } + const guild = await interaction.client.guilds.fetch(found.guildID) + const channel = await guild.channels.fetch(found.channelID) + const message = await channel.messages.fetch(found.messageID) + + var msgData = { + content: message.content, + author: await message.author, + reference: await message.reference, + embed: await message.embeds ? 'embed' : null + } // debug + + quotesColl.findOneAndUpdate({ + messageID: found.messageID + },{ + $inc: { count: 1} + },{ + upsert: true + }) + + if (msgData.reference) { + let refMessage = await channel.messages.fetch(msgData.reference.messageId) + var refData = { + content: refMessage.content, + author: await refMessage.author, + embed: await refMessage.embeds.length > 0 ? 'embed' : null + } + } + + var description = '' + if (refData) { + description += `> ${refData.author}` + if (refData.embed) { + description += '*an embed / a command* ' + } else { + description += refData.content + } + description += `\r\n↳` + } + let messageLink = `https://discord.com/channels/${found.guildID}/${found.channelID}/${found.messageID}` + description += `${msgData.author} ${msgData.content}\r\n\r\n${messageLink}` + let timestamp = new Date(message.createdTimestamp) + let footer = timestamp.toDateString().toString() + + const embed = new EmbedBuilder() + .setThumbnail(msgData.author.displayAvatarURL()) + .setURL(messageLink) + .setTitle(`- Quote Found! -`) + .setDescription(description) + .setFooter({ text: (footer + ' #' + found.messageID) }) + await interaction.reply({ embeds: [embed] }) +} +async function quotesList(interaction) { + const embed = new EmbedBuilder() + .setTitle('- Quotes List! -') + .setDescription('- Choose someone below to filter by User') + .setThumbnail(interaction.guild.iconURL()) + const row = new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setEmoji(`◀`) + .setCustomId('quotes_list_left') + .setStyle(ButtonStyle.Primary) + ) + .addComponents( + new ButtonBuilder() + .setEmoji(`❌`) + .setCustomId('abort') + .setStyle(ButtonStyle.Primary) + ) + .addComponents( + new ButtonBuilder() + .setEmoji(`▶`) + .setCustomId('quotes_list_right') + .setStyle(ButtonStyle.Primary) + ) + + const select = new ActionRowBuilder() + .addComponents( + new UserSelectMenuBuilder() + .setCustomId('quotes_list_mentionable') + .setPlaceholder('Filter by User') + ) + + await interaction.reply({ + embeds: [embed], + components: [select, row], + ephemeral: true + }) + + } async function quotesLeaderboard(interaction) { - + // need to add count to quotes } module.exports = { data: new SlashCommandBuilder() @@ -106,14 +301,19 @@ module.exports = { s .setName('random') .setDescription('get a random quote') - .addUserOption(o => o.setName('target').setDescription('by user'))) + .addUserOption(o => o.setName('by').setDescription('by user'))) .addSubcommand(s => s .setName('leaderboard') - .setDescription('see the most used quotes')), + .setDescription('see the most used quotes')) + .addSubcommand(s => + s + .setName('list') + .setDescription('[ADMIN] list all quotes')), async execute(interaction) { switch (interaction.options._subcommand) { case 'add': + await interaction.deferReply() quotesAdd(interaction) break; case 'remove': @@ -128,6 +328,9 @@ module.exports = { case 'leaderboard': quotesLeaderboard(interaction) break; + case 'list': + quotesList(interaction) + break; default: break; } diff --git a/commands/test/ping.js b/commands/test/ping.js deleted file mode 100644 index cd2dde7..0000000 --- a/commands/test/ping.js +++ /dev/null @@ -1,11 +0,0 @@ -const { SlashCommandBuilder } = require('discord.js') -module.exports = { - data: new SlashCommandBuilder() - .setName('ping') - .setDescription('returns pong'), - async execute(interaction) { - await interaction.deferReply() - await interaction.editReply('pong!') - await interaction.followUp('another pong!') - } -} \ No newline at end of file diff --git a/events/DistubeError.js b/events/DistubeError.js new file mode 100644 index 0000000..a68ffe1 --- /dev/null +++ b/events/DistubeError.js @@ -0,0 +1,10 @@ +module.exports = { + name: 'DistubeError', + once: true, + async execute(channel, error) { + console.log({ + channel: channel, + error: error + }) + } +} \ No newline at end of file diff --git a/events/VoiceStateUpdates.js b/events/VoiceStateUpdates.js index 960f7c6..782541c 100644 --- a/events/VoiceStateUpdates.js +++ b/events/VoiceStateUpdates.js @@ -1,50 +1,57 @@ -const { Events, ClientVoiceManager } = require("discord.js"); -const { getVoiceConnection } = require('@discordjs/voice') -require('dotenv').config() -const { client } = require('../index') -const users_in_afk = new Set(); -const delay = ms => new Promise(res => setTimeout(res, ms)); -var connected = false; -const playlist = `https://www.youtube.com/playlist?list=PLjSh2s1ASTgsSdjCgFbpo18RAYF_dHf46` +// const { Events, ClientVoiceManager } = require("discord.js"); +// const { getVoiceConnection } = require('@discordjs/voice') +// require('dotenv').config() +// const { client } = require('../index'); +// const users_in_afk = new Set(); +// const delay = ms => new Promise(res => setTimeout(res, ms)); +// var connected = false; +// const url = `https://www.youtube.com/watch?v=Y4ySxP_IptE` -module.exports = { - name: Events.VoiceStateUpdate, - once: false, - async execute(oldState, newState) { - const guild = client.guilds.cache.get(process.env.D_GuildID) - const afk_channel = await guild.channels.fetch(guild.afkChannelId) - const real_afk_channel = await guild.channels.fetch(process.env.D_RealTartarosID) - const user = await guild.members.fetch(newState.id) +// module.exports = { +// name: Events.VoiceStateUpdate, +// once: false, +// async execute(oldState, newState) { +// const guild = client.guilds.cache.get(process.env.D_GuildID) +// const afk_channel = await guild.channels.fetch(guild.afkChannelId) +// const real_afk_channel = await guild.channels.fetch(process.env.D_RealTartarosID) +// const user = await guild.members.fetch(newState.id) - if(user.id === process.env.D_ID) return; +// if(user.id === process.env.D_ID) return; - // if someone enters the official AFK channel, move them to one where we can play music - if (newState.channelId === afk_channel.id) { - await delay(1000) +// // if someone enters the official AFK channel, move them to one where we can play music +// if (newState.channelId === afk_channel.id) { +// await delay(1000) - await user.voice.setChannel(real_afk_channel) - users_in_afk.add(newState.id) - console.log(`${users_in_afk.size} User(s) in Channel`) +// await user.voice.setChannel(real_afk_channel) + +// users_in_afk.add(newState.id) +// console.log(`${users_in_afk.size} User(s) in Channel`) - if (!connected) { - connected = true; - await client.distube.voices.join(real_afk_channel) - await client.distube.play(real_afk_channel, "https://www.youtube.com/watch?v=dQw4w9WgXcQ") - const queue = client.distube.getQueue(guild) - await queue.setRepeatMode('Queue') - await queue.setVolume(40) - } - } +// if (!connected) { +// connected = true; +// await client.distube.voices.join(real_afk_channel) +// await user.voice.setSuppressed(true) // mute user? +// await guild.members.me.voice.setSuppressed(false); //unmute self +// await client.distube.play(real_afk_channel, url, { +// member: newState.member, +// }) +// //const queue = client.distube.getQueue(guild) +// //await queue.setRepeatMode(2) +// //await queue.setVolume(40) +// } +// } - // if someone leaves the real AFK channel, remove them from cache but wait for rejoiners, then leave if none are here - if (oldState.channelId === real_afk_channel.id && oldState.channelId != newState.channelId) { - users_in_afk.delete(oldState.id) - } +// // if someone leaves the real AFK channel, remove them from cache but wait for rejoiners, then leave if none are here +// if (oldState.channelId === real_afk_channel.id && oldState.channelId != newState.channelId) { +// users_in_afk.delete(oldState.id) +// const user = await guild.members.fetch(oldState.id) +// //await user.voice.setMute(false) //kann nicht unmuten wenn disconnected ist +// } - if (users_in_afk.size === 0) { - //leave if empty - await client.distube.voices.leave(real_afk_channel) - connected = false; - } - } -} \ No newline at end of file +// if (users_in_afk.size === 0) { +// //leave if empty +// await client.distube.voices.leave(real_afk_channel) +// connected = false; +// } +// } +// } \ No newline at end of file diff --git a/handlers/legacyCommands.js b/handlers/legacyCommands.js index 78575fb..17d3119 100644 --- a/handlers/legacyCommands.js +++ b/handlers/legacyCommands.js @@ -1,29 +1,29 @@ const fs = require('node:fs') const path = require('node:path') module.exports = (client) => { - const legacyFoldersPath = path.join(__dirname, '../legacyCommands'); - const legacyCommandFolders = fs.readdirSync(legacyFoldersPath); - let legacyCount = 0 - let aliasCount = 0 - for (const folder of legacyCommandFolders) { - const commandsPath = path.join(legacyFoldersPath, folder); - const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js')); - for (const file of commandFiles) { - legacyCount++ - const filePath = path.join(commandsPath, file); - const command = require(filePath); - if ('execute' in command) { - client.legacyCommands.set(command.name, command); - } - if (command.aliases && Array.isArray(command.aliases)) { - command.aliases.forEach(alias => { - aliasCount++ - client.aliases.set(alias, command.name) - }) - } - } - } - console.log(`[${aliasCount}] Aliase(s) initialized`) - console.log(`[${legacyCount}] Legacy Command(s) initialized`) + // const legacyFoldersPath = path.join(__dirname, '../legacyCommands'); + // const legacyCommandFolders = fs.readdirSync(legacyFoldersPath); + // let legacyCount = 0 + // let aliasCount = 0 + // for (const folder of legacyCommandFolders) { + // const commandsPath = path.join(legacyFoldersPath, folder); + // const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js')); + // for (const file of commandFiles) { + // legacyCount++ + // const filePath = path.join(commandsPath, file); + // const command = require(filePath); + // if ('execute' in command) { + // client.legacyCommands.set(command.name, command); + // } + // if (command.aliases && Array.isArray(command.aliases)) { + // command.aliases.forEach(alias => { + // aliasCount++ + // client.aliases.set(alias, command.name) + // }) + // } + // } + // } + // console.log(`[${aliasCount}] Aliase(s) initialized`) + // console.log(`[${legacyCount}] Legacy Command(s) initialized`) } diff --git a/index.js b/index.js index 7a14d1a..3de4359 100644 --- a/index.js +++ b/index.js @@ -27,8 +27,11 @@ client.aliases = new Collection() // list of command aliases client.buttons = new Collection() // list of buttons client.selectMenus = new Collection() // list of selectMenus +// Initialize DisTube with YtDlpPlugin and request options const distube = new DisTube(client, { - plugins: [new YtDlpPlugin({ update: true })], + plugins: [ + new YtDlpPlugin(), + ], }); client.distube = distube @@ -37,4 +40,6 @@ fs.readdirSync('./handlers').forEach((handler) => { require(`./handlers/${handler}`)(client) }); + +distube.on('error', (channel, error) => {client.emit('DistubeError', (channel, error))}) client.login(process.env.D_Token) \ No newline at end of file diff --git a/legacyCommands/test/interactive.js b/legacyCommands/test/interactive.js deleted file mode 100644 index fc3d3e4..0000000 --- a/legacyCommands/test/interactive.js +++ /dev/null @@ -1,16 +0,0 @@ -const { ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js') -module.exports = { - name: 'interactive', - description: 'testing interactive buttons', - async execute(message, args) { - const row = new ActionRowBuilder() - .addComponents( - new ButtonBuilder() - .setLabel('Test') - .setStyle(ButtonStyle.Primary) - .setCustomId('test_button_1') - ) - - await message.reply({ content: 'Here is an interactive button:', components: [row] }); - } -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 65e4e13..f1f3819 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "@discordjs/opus": "^0.9.0", "@discordjs/voice": "^0.17.0", "@distube/yt-dlp": "^2.0.1", "discord.js": "^14.15.3", @@ -63,6 +64,300 @@ "url": "https://github.com/discordjs/discord.js?sponsor" } }, + "node_modules/@discordjs/node-pre-gyp": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/@discordjs/node-pre-gyp/-/node-pre-gyp-0.4.5.tgz", + "integrity": "sha512-YJOVVZ545x24mHzANfYoy0BJX5PDyeZlpiJjDkUBM/V/Ao7TFX9lcUvCN4nr0tbr5ubeaXxtEBILUrHtTphVeQ==", + "license": "BSD-3-Clause", + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "license": "ISC", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@discordjs/node-pre-gyp/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, + "node_modules/@discordjs/opus": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@discordjs/opus/-/opus-0.9.0.tgz", + "integrity": "sha512-NEE76A96FtQ5YuoAVlOlB3ryMPrkXbUCTQICHGKb8ShtjXyubGicjRMouHtP1RpuDdm16cDa+oI3aAMo1zQRUQ==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@discordjs/node-pre-gyp": "^0.4.5", + "node-addon-api": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/@discordjs/rest": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.3.0.tgz", @@ -263,6 +558,41 @@ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agent-base/node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/agent-base/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "license": "MIT" + }, "node_modules/ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -378,6 +708,15 @@ "node": ">=0.10.0" } }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -506,6 +845,12 @@ "url": "https://dotenvx.com" } }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -608,6 +953,42 @@ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "license": "MIT" + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -721,6 +1102,30 @@ "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.10.0.tgz", "integrity": "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ==" }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/memory-pager": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", @@ -848,6 +1253,54 @@ "node": ">= 4.4.x" } }, + "node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", + "license": "MIT" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/node-gyp-build": { "version": "4.8.1", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", @@ -883,6 +1336,7 @@ "version": "3.1.4", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.4.tgz", "integrity": "sha512-wjPBbFhtpJwmIeY2yP7QF+UKzPfltVGtfce1g/bB15/8vCGZj8uxD62b/b9M9/WVgme0NZudpownKN+c0plXlQ==", + "license": "MIT", "dependencies": { "chokidar": "^3.5.2", "debug": "^4", diff --git a/package.json b/package.json index 1804a71..dafbf22 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ }, "homepage": "https://github.com/DeSqBlocki/Arthonor-3#readme", "dependencies": { + "@discordjs/opus": "^0.9.0", "@discordjs/voice": "^0.17.0", "@distube/yt-dlp": "^2.0.1", "discord.js": "^14.15.3", diff --git a/selectMenus/honors/honor_menu_mentionable.js b/selectMenus/honors/honor_menu_mentionable.js index 49b5a3e..ec7b5f3 100644 --- a/selectMenus/honors/honor_menu_mentionable.js +++ b/selectMenus/honors/honor_menu_mentionable.js @@ -1,4 +1,4 @@ -const { EmbedBuilder, ActionRowBuilder, MentionableSelectMenuBuilder, UserSelectMenuBuilder, PermissionFlagsBits } = require("discord.js") +const { EmbedBuilder, ActionRowBuilder, UserSelectMenuBuilder, PermissionFlagsBits } = require("discord.js") const { mClient } = require("../..") require('dotenv').config() @@ -20,17 +20,16 @@ module.exports = { const member = interaction.message.guild.members.cache.get(target.user.id) const memberRoles = member.roles.cache - .filter((roles) => roles.id !== interaction.message.guild.id) - .map((role) => role.toString()) - // var userHas = member.permissions.toArray() // Scratched Idea for Menu - + .filter((roles) => roles.id !== interaction.message.guild.id) + .map((role) => role.toString()) + const description = String(`${target} - ${target.user.globalName ?? target.user.username} - ${target.user.id}\r\n\r\n${memberRoles}`).replaceAll(',', ' ') embed.setTitle(`- User Stats -`) .setDescription(description) .addFields({ name: 'Current Honor Level:', value: `${theirHonorLevel?.honors ?? 0}`, inline: true }) - .setFooter({text: 'Honor Level updaten sich nicht automatisch!'}) + .setFooter({ text: 'Honor Level updaten sich nicht automatisch!' }) } const select = new ActionRowBuilder() .addComponents( @@ -39,8 +38,6 @@ module.exports = { .setPlaceholder('Select a User') ) - - const row = interaction.message.components[1] await interaction.update({ embeds: [embed], diff --git a/selectMenus/quotes/quotes_list_mentionable.js b/selectMenus/quotes/quotes_list_mentionable.js new file mode 100644 index 0000000..748918d --- /dev/null +++ b/selectMenus/quotes/quotes_list_mentionable.js @@ -0,0 +1,47 @@ +const { EmbedBuilder, ActionRowBuilder, UserSelectMenuBuilder, PermissionFlagsBits, RoleSelectMenuComponent, UserSelectMenuComponent } = require("discord.js") +const { mClient } = require("../..") +require('dotenv').config() + +module.exports = { + name: 'quotes_list_mentionable', + description: 'handles quotes list mentionables', + async execute(interaction) { + const embedData = await interaction.message.embeds[0].data + const embed = new EmbedBuilder() + if (!interaction.members) { + embed.setTitle(embedData.title) + .setThumbnail(embedData.thumbnail.url) + .setDescription(embedData.description); + } else { + const target = await interaction.guild.members.fetch(interaction.members.keys().next().value) + const db = mClient.db(process.env.M_DB) + const quotesColl = db.collection('quotes') + const quotes = await quotesColl.find({ by: target.id }).toArray() + const member = interaction.message.guild.members.cache.get(target.user.id) + const memberRoles = member.roles.cache + .filter((roles) => roles.id !== interaction.message.guild.id) + .map((role) => role.toString()) + + const description = String(`${target}\r\n\r\n${memberRoles}`).replaceAll(',', ' ') + embed.setTitle(`- User Stats -`) + .setDescription(description) + .setThumbnail(target.displayAvatarURL()) + .addFields({ + name: 'Number of Quotes:', value: `${quotes.length}`, inline: true + }) + .setFooter({ text: (`${new Date().toLocaleDateString('en-US', { weekday: 'short' })} ${new Date().toLocaleDateString('en-US', { month: 'short' })} ${new Date().getDate()} ${new Date().getFullYear()} UserID <@${member.id}>`) }) + } + const select = new ActionRowBuilder() + .addComponents( + new UserSelectMenuBuilder() + .setCustomId('quotes_list_mentionable') + .setPlaceholder('Filter By User') + ) + + const row = interaction.message.components[1] + await interaction.update({ + embeds: [embed], + components: [select, row] + }) + } +} \ No newline at end of file