diff --git a/commands/misc/EC.js b/commands/Selmer Specific/EC.js similarity index 100% rename from commands/misc/EC.js rename to commands/Selmer Specific/EC.js diff --git a/commands/misc/arrow.js b/commands/Selmer Specific/arrow.js similarity index 100% rename from commands/misc/arrow.js rename to commands/Selmer Specific/arrow.js diff --git a/commands/misc/postProfile.js b/commands/Selmer Specific/postProfile.js similarity index 100% rename from commands/misc/postProfile.js rename to commands/Selmer Specific/postProfile.js diff --git a/commands/misc/quotes.js b/commands/Selmer Specific/quotes.js similarity index 100% rename from commands/misc/quotes.js rename to commands/Selmer Specific/quotes.js diff --git a/commands/admin/setup.js b/commands/admin/setup.js new file mode 100644 index 0000000..db32dbe --- /dev/null +++ b/commands/admin/setup.js @@ -0,0 +1,58 @@ +//@ts-check +const { MongoClient, ServerApiVersion } = require('mongodb'); +const { CreateNewCollection } = require("../db/econ"); + + +async function setWelcomeChannel(dbo, message, channelname) { + const channel = message.guild.channels.cache.find(ch => ch.name === channelname); + dbo.insertOne({welcomechannel: channel}); +} + + + +async function execute(bot, message, args, command, Discord, mongouri, items, xp_collection) { + const server = message.guild.id; + const owner = message.guild.members.cache.get(message.guild.ownerId); + + if (message.author.id != message.guild.ownerId) { + return message.reply('Only the server owner can do this!') + } + + // @ts-ignore + const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 }); + if (client.writeConcern || client.writeConcern) { + client.close(); + return message.reply("Something went wrong with the database, please try again later and contact support if this problem persists!"); + } + + //Initialize + CreateNewCollection(message, client, server, owner.user.id); + + client.connect(err => { + if (err) { return console.log(err); } + + const db = client.db(server); + const dbo = db.collection('SETUP'); + + //Chose the appropriate command + command = args[0]; + if (command == 'welcomechannel') { + if (args.length != 2) { return message.reply('The command format is _!setup welcomechannel _'); } + // setWelcomeChannel(dbo, message, args[1]); + const channel = message.guild.channels.cache.find(ch => ch.name === args[1]); + dbo.updateOne({welcomechannel: {$exists: true}}, {$set: {welcomechannel: `${channel.id}`}}); + } + }); + + client.close(); +} + + + + + +module.exports = { + name: 'setup', + description: 'N/A', + execute +} \ No newline at end of file diff --git a/commands/admin/wallpaper.jpg b/commands/admin/wallpaper.jpg new file mode 100644 index 0000000..9634bc0 Binary files /dev/null and b/commands/admin/wallpaper.jpg differ diff --git a/commands/admin/welcome.js b/commands/admin/welcome.js new file mode 100644 index 0000000..4c0e72a --- /dev/null +++ b/commands/admin/welcome.js @@ -0,0 +1,76 @@ +const { MessageAttachment } = require('discord.js'); +const { readFile } = require('fs/promises'); + +const { request } = require('undici'); +const CanvasImport = require('@napi-rs/canvas'); +const canvas = CanvasImport.createCanvas(700, 250) +const context = canvas.getContext('2d') + +//https://some-random-api.ml/welcome +async function welcome(member, welcomechannel, welcomebanner = null) { + + //Draw Stuff + const context = canvas.getContext('2d'); + + const backgroundFile = await readFile('./commands\\admin\\wallpaper.jpg'); + const background = new CanvasImport.Image(); + background.src = backgroundFile; + + // This uses the canvas dimensions to stretch the image onto the entire canvas + context.drawImage(background, 0, 0, canvas.width, canvas.height); + + //Draw the Border + context.strokeStyle = '#0099ff'; + context.strokeRect(0, 0, canvas.width, canvas.height); + + + //Add Text + + //have the function here, because returns are whack + const applyText = (canvas, text) => { + const context = canvas.getContext('2d'); + + // Declare a base size of the font + let fontSize = 70; + + do { + // Assign the font to the context and decrement it so it can be measured again + context.font = `italic ${fontSize -= 10}px sans-serif`; + // Compare pixel width of the text to the canvas minus the approximate avatar size + } while (context.measureText(text).width > canvas.width - 100); + + // Return the result to use in the actual canvas + return context.font; + }; + + //message.author.username == interaction.member.displayName + //message.guild.name == interaction.member.guild.name + const text = `Welcome to ${member.guild.name} ${member.user.username}#${member.user.discriminator}!`; + context.font = applyText(canvas, text); + context.fillStyle = '#ffffff'; + context.fillText(text, (canvas.width/2) - (text.length * 7.5), canvas.height - 15); + + + //ANYTHING DRAWN AFTER THIS WILL BE CLIPPED!!! + //Make whatever image will be draw (the user's avatar) into a circular format + context.beginPath(); + context.arc((canvas.width/2), 90, 80, 0, Math.PI * 2, true); + context.closePath(); + + // Clip off the region you just drew (enforce template?) + context.clip(); + + + //Add the user's profile pic (message.author == interaction.user) + const { body } = await request(member.displayAvatarURL({ format: 'jpg' })); + const avatar = new CanvasImport.Image(); + avatar.src = Buffer.from(await body.arrayBuffer()); + context.drawImage(avatar, (canvas.width/2) - 80, 10, 160, 160); + + // Use the helpful Attachment class structure to process the file for you + const attachment = new MessageAttachment(canvas.toBuffer('image/png'), 'profile-image.png'); + + welcomechannel.send({ files: [attachment] }); +} + +module.exports = { welcome } \ No newline at end of file diff --git a/commands/db/econ.js b/commands/db/econ.js index 2c73dd5..45452d3 100644 --- a/commands/db/econ.js +++ b/commands/db/econ.js @@ -116,7 +116,10 @@ function convertCurrency(id, amt, dbo) { function checkAndUpdateBal(dbo, item, message, args) { let b = false; dbo.find({"balance": {$exists: true}}).toArray(b = function(err, doc) { - if (!String(doc)) { return message.reply("Your account doesn't exist, please contact the mods for support"); } + if (!String(doc)) { + message.reply("Your account doesn't exist, please contact the mods for support"); + return false; + } const icost = args[0] * item.cost; if (doc[0].balance < icost) { diff --git a/commands/misc/meme.js b/commands/misc/meme.js index 46bc99f..edeb83b 100644 --- a/commands/misc/meme.js +++ b/commands/misc/meme.js @@ -16,6 +16,24 @@ module.exports = { .setImage(meme.image); message.channel.send({ embeds: [newEmbed] }); - }) + }).catch(async err => { + console.log(err); + //Try a different way + const fetch = require('node-fetch'); + const response = await fetch('https://some-random-api.ml/meme'); + const data = await response.json().catch(err => { + console.log(err); + return message.reply("_Uh oh, something's gone wrong!_"); + }); + + const newEmbed = new Discord.MessageEmbed() + .setColor(randomHexColor()) + .setTitle(data.caption) + // .setURL(data.image) + .setDescription(`category: ${data.category}`) + .setImage(data.image); + + message.channel.send({ embeds: [newEmbed] }); + }); } } \ No newline at end of file diff --git a/main.js b/main.js index de3922b..814d342 100644 --- a/main.js +++ b/main.js @@ -1,8 +1,9 @@ -const { Client, Intents, Permissions } = require('discord.js'); +const { Client, Intents, MessageActionRow, MessageButton, MessageSelectMenu } = require('discord.js'); const Discord = require('discord.js'); const { MongoClient, ServerApiVersion } = require('mongodb'); const fs = require('fs'); const turnManager = require('./commands/turnManager.js'); +const { welcome } = require('./commands/admin/welcome.js'); const { exit } = require('process'); const BASE_LVL_XP = 20; @@ -29,7 +30,9 @@ const bot = new Client({ Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_MESSAGE_REACTIONS, Intents.FLAGS.GUILD_VOICE_STATES, - Intents.FLAGS.GUILD_EMOJIS_AND_STICKERS + Intents.FLAGS.GUILD_EMOJIS_AND_STICKERS, + Intents.FLAGS.GUILD_PRESENCES, + Intents.FLAGS.GUILD_MEMBERS ], }); @@ -51,15 +54,28 @@ const mongouri = mongouritemp; const { connect } = require('mongoose'); bot.on("guildCreate", guild => { - guild.members.fetch guild.roles.create({ name: 'Selmer Bot Mod' }); - const role = guild.roles.cache.find((role) => role.name === 'Selmer Bot Mod'); // member.roles.cache.has('role-id-here'); - let owner = guild.members.cache.fetch(guild.ownerID); - owner.send('Thank you for adding Selmer Bot to your server!\nPlease give people you want to have access to Selmer Bot\'s restricted commands the <@&' + role + '> role.'); + //const role = guild.roles.cache.find((role) => role.name === 'Selmer Bot Mod'); // member.roles.cache.has('role-id-here'); + const server = bot.guilds.cache.get(guild.id); + const owner = server.members.fetch(guild.ownerId).then(function(owner) { + owner.send('Thank you for adding Selmer Bot to your server!\nPlease give people you want to have access to Selmer Bot\'s restricted commands the "_Selmer Bot Mod_" role.'); + owner.send('To help set up Selmer Bot to work better with your server, use _!setup help_ in a channel Selmer Bot is in!'); + }); + //Set up the server + const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 }); + client.connect(err => { + if (err) { return console.log(err); } + + const dbo = client.db(guild.id).collection('SETUP'); + dbo.insertMany([{_id: 'WELCOME', 'welcomechannel': null, 'welcomebanner': null}]); + }); + + client.close(); }); + //MongoDB Integration end // let item = items.filter(function (item) { return item.name.toLowerCase() == 'grapes'; }); @@ -83,11 +99,11 @@ fs.readdirSync('./commands') //Set these two manually because all the seperate games can't be included in the command list (all managed by the 'game' file) - let temp_command = require("./commands/db/econ.js"); +let temp_command = require("./commands/db/econ.js"); const { STATE } = require('./commands/db/econ.js'); - bot.commands.set('econ', temp_command); - temp_command = require('./commands/db/game.js'); - bot.commands.set('game', temp_command); +bot.commands.set('econ', temp_command); +temp_command = require('./commands/db/game.js'); +bot.commands.set('game', temp_command); // const econFiles = fs.readdirSync('./commands/inventory').filter(file => file.endsWith('.js'));; // const currency = new Discord.Collection(); @@ -136,38 +152,78 @@ bot.on('ready', async () => { //Button Section bot.on('interactionCreate', async interaction => { - if (!interaction.isButton()) return; + if (interaction.isButton()) { + const battlecommandlist = ['ATTACK', 'HEAL', 'DEFEND', 'ITEMS']; + + const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 }); + client.connect(err => { + + if (battlecommandlist.indexOf(interaction.customId) != -1) { + let current_user = turnManager.getTurn(client, bot, interaction); + + current_user.then(function (result) { + const id = result[0]; + const doc = result[1]; + const threadname = doc.thread; + const dbo = client.db(interaction.guildId + '[ECON]').collection(id); + + dbo.find({ 'state': {$exists: true} }).toArray(async function (err, docs) { + if (interaction.user.id == id) { + await interaction.deferReply(); + + //Check State + if (docs[0].state == STATE.FIGHTING) { + //Do turn stuff + bot.commands.get('game').in_game_redirector(bot, interaction, threadname, doc, client, mongouri, items, xp_collection); + } + + //remove the old interation message + interaction.message.delete(); + + interaction.editReply(`<@${interaction.user.id}> used _${interaction.customId.toLowerCase()}_!`); + } else { + console.log("It's not your turn!"); + } + }); + }); + } //else ifs here + }); + + client.close(); + } + else if (interaction.isCommand()) { + + } +}); + + +//Welcome new members +bot.on('guildMemberAdd', async (member) => { + //Check for impartial data + if(member.partial) await member.fetch(); const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 }); + + const guild = bot.guilds.cache.get(member.guild.id); + client.connect(err => { - let current_user = turnManager.getTurn(client, bot, interaction); - - current_user.then(function (result) { - const id = result[0]; - const doc = result[1]; - const threadname = doc.thread; - const dbo = client.db(interaction.guildId + '[ECON]').collection(id); + const dbo = client.db(member.guild.id).collection('SETUP'); - dbo.find({ 'state': {$exists: true} }).toArray(async function (err, docs) { - if (interaction.user.id == id) { - await interaction.deferReply(); + dbo.find({_id: 'WELCOME'}).toArray(async (err, docs) => { + var welcomechannel; + if (docs[0].welcomechannel == null) { + welcomechannel = guild.channels.cache.find(channel => channel.name.toLowerCase() === 'welcome'); + } else { + welcomechannel = guild.channels.cache.get(docs[0].welcomechannel) + } - //Check State - if (docs[0].state == STATE.FIGHTING) { - //Do turn stuff - bot.commands.get('game').in_game_redirector(bot, interaction, threadname, doc, client, mongouri, items, xp_collection); - } - - //remove the old interation message - // interaction.message.delete(); - - interaction.editReply(`<@${interaction.user.id}> used _${interaction.customId.toLowerCase()}_!`); - } else { - console.log("It's not your turn!"); - } - }); - }); - }); + if (welcomechannel == null) { + return console.log('No welcome channel detected'); + } + + await welcome(member, welcomechannel, docs[0].welcomebanner); + }) + }) }); @@ -180,6 +236,19 @@ bot.on('messageCreate', (message) => { const args = message.content.slice(prefix.length).split(' '); const command = args.shift().toLowerCase(); + + if (command == 'welcome') { + const row = new MessageActionRow() + .addComponents( + new MessageButton() + .setCustomId('WELCOME') + .setLabel('WELCOME') + .setStyle('PRIMARY') + ); + + message.channel.send({ components: [row] }); + } + //Check if the user has sufficient permission //Performes the command //Admin section @@ -187,14 +256,14 @@ bot.on('messageCreate', (message) => { else if(bot.commands.has(command) && command != 'ECON') { //Database access is required, change the inputs - if (command == 'game' || command == 'accept') { + if (command == 'game' || command == 'accept' || command == 'setup') { bot.commands.get(command).execute(bot, message, args, command, Discord, mongouri, items, xp_collection); } else { bot.commands.get(command).execute(message, args, Discord, Client, bot); } } - //Catch + //Econ and also the catch statement else { bot.commands.get('econ').execute(bot, message, args, command, Discord, mongouri, items, xp_collection); } }) diff --git a/package-lock.json b/package-lock.json index 288edb3..262069c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,8 +11,10 @@ "dependencies": { "@discordjs/opus": "github:discordjs/opus", "@discordjs/voice": "^0.8.0", + "@napi-rs/canvas": "^0.1.22", "apt": "^0.0.2", "axios": "^0.27.2", + "canvas": "^2.9.1", "cheerio": "^1.0.0-rc.10", "discord-reply": "^0.1.2", "discord.js": "^13.6.0", @@ -29,6 +31,7 @@ "sequelize": "^6.19.0", "sqlite3": "^5.0.3", "sudo": "^1.0.3", + "undici": "^5.4.0", "youtube-mp3-downloader": "^0.7.10", "ytdl-core": "^4.11.0", "ytdl-core-discord": "^1.3.1" @@ -242,6 +245,164 @@ "node": ">=8" } }, + "node_modules/@napi-rs/canvas": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas/-/canvas-0.1.22.tgz", + "integrity": "sha512-9TMsOCVOWWIczEM0Mxhvmsj4GWdBdYOMYYo1kilGgZLRQjD01wdbNnrxDUPTAigxpQXSk8tFhURtXrJUWafcvQ==", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@napi-rs/canvas-android-arm64": "0.1.22", + "@napi-rs/canvas-darwin-arm64": "0.1.22", + "@napi-rs/canvas-darwin-x64": "0.1.22", + "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.22", + "@napi-rs/canvas-linux-arm64-gnu": "0.1.22", + "@napi-rs/canvas-linux-arm64-musl": "0.1.22", + "@napi-rs/canvas-linux-x64-gnu": "0.1.22", + "@napi-rs/canvas-linux-x64-musl": "0.1.22", + "@napi-rs/canvas-win32-x64-msvc": "0.1.22" + } + }, + "node_modules/@napi-rs/canvas-android-arm64": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-android-arm64/-/canvas-android-arm64-0.1.22.tgz", + "integrity": "sha512-Qj0TgzUu5aq9r2lD/zruqeZ22DIrQS7X8nuaqtqk5UL+q5nGcPR39VRa3vyLZSktzw0eNxFDFyqKoUshUd/Qpw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-darwin-arm64": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-arm64/-/canvas-darwin-arm64-0.1.22.tgz", + "integrity": "sha512-w6fcPbFPT8r3istcKBGKef11PBjAAQPWj8/KqDdoui8/tzuE0QsSkcnq8OTjfECzflgagPweM824Ua8KC2v9XA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-darwin-x64": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-x64/-/canvas-darwin-x64-0.1.22.tgz", + "integrity": "sha512-qgm9bIAZ408xFmB8L+7AcK2onii10wUUEJzKr6+Xi6CvXRCcGC2Mu3qHKTaRiV3OCPzS4RxGyXC05fahhRqRLQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-arm-gnueabihf": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm-gnueabihf/-/canvas-linux-arm-gnueabihf-0.1.22.tgz", + "integrity": "sha512-FmsK7I3BZoq9DBOIDo/y/MrbCjNqEkaFCN+bMx2k87y8kILrJKAPKCgqXjrj6OW+zisd33kHruFPALA3GrLZIQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-arm64-gnu": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-gnu/-/canvas-linux-arm64-gnu-0.1.22.tgz", + "integrity": "sha512-/um5HVrR7mJsAj3tA39TzTANT+LfpBc2blA9isMtsjlgfGKQow4BZUzyQTAptJz/69MMElo4g9STaitBrDNbmQ==", + "cpu": [ + "arm64" + ], + "hasInstallScript": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-arm64-musl": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-musl/-/canvas-linux-arm64-musl-0.1.22.tgz", + "integrity": "sha512-Qz58HSP62fQvnKIy0z6NbIwf66WNQH0GWOMl+QwVWJR7SdxtmY4+gletBrNkBkZo5I6u8D1WcODLKRZSMn0MGA==", + "cpu": [ + "arm64" + ], + "hasInstallScript": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-x64-gnu": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-gnu/-/canvas-linux-x64-gnu-0.1.22.tgz", + "integrity": "sha512-S/Bgcc3088emN3M6wl5ql+luGSh+6UIGwsldFCS1m8/3cBTs/IsEY++w4ef7PB30x2ScbcEjQPXrAGpyIct1oA==", + "cpu": [ + "x64" + ], + "hasInstallScript": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-x64-musl": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-musl/-/canvas-linux-x64-musl-0.1.22.tgz", + "integrity": "sha512-WaJyxWb9QvYlkrCdOCgYTnWCTNJD+9UmWoIurpV9+rb2YvGuhovF3EkpqtQKiQNb1+GkcQ2LNfcGD/d0YKdqxg==", + "cpu": [ + "x64" + ], + "hasInstallScript": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-win32-x64-msvc": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-x64-msvc/-/canvas-win32-x64-msvc-0.1.22.tgz", + "integrity": "sha512-6Gx4TCsoF3eAFlgD9q1fVE8ee+/AiQlKvZ+vXRFtdbyFkTYGDknm01M+xHJXssBG8BYPOsMZtNzFjM1r8hQagg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@npmcli/fs": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", @@ -2895,6 +3056,14 @@ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.3.tgz", "integrity": "sha512-QvjkYpiD+dJJraRA8+dGAU4i7aBbb2s0S3jA45TFOvg2VgqvdCDd/3N6CqA8gluk1W91GLoXg5enMUx560QzuA==" }, + "node_modules/undici": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.4.0.tgz", + "integrity": "sha512-A1SRXysDg7J+mVP46jF+9cKANw0kptqSFZ8tGyL+HBiv0K1spjxPX8Z4EGu+Eu6pjClJUBdnUPlxrOafR668/g==", + "engines": { + "node": ">=12.18" + } + }, "node_modules/unique-filename": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", @@ -3357,6 +3526,76 @@ } } }, + "@napi-rs/canvas": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas/-/canvas-0.1.22.tgz", + "integrity": "sha512-9TMsOCVOWWIczEM0Mxhvmsj4GWdBdYOMYYo1kilGgZLRQjD01wdbNnrxDUPTAigxpQXSk8tFhURtXrJUWafcvQ==", + "requires": { + "@napi-rs/canvas-android-arm64": "0.1.22", + "@napi-rs/canvas-darwin-arm64": "0.1.22", + "@napi-rs/canvas-darwin-x64": "0.1.22", + "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.22", + "@napi-rs/canvas-linux-arm64-gnu": "0.1.22", + "@napi-rs/canvas-linux-arm64-musl": "0.1.22", + "@napi-rs/canvas-linux-x64-gnu": "0.1.22", + "@napi-rs/canvas-linux-x64-musl": "0.1.22", + "@napi-rs/canvas-win32-x64-msvc": "0.1.22" + } + }, + "@napi-rs/canvas-android-arm64": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-android-arm64/-/canvas-android-arm64-0.1.22.tgz", + "integrity": "sha512-Qj0TgzUu5aq9r2lD/zruqeZ22DIrQS7X8nuaqtqk5UL+q5nGcPR39VRa3vyLZSktzw0eNxFDFyqKoUshUd/Qpw==", + "optional": true + }, + "@napi-rs/canvas-darwin-arm64": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-arm64/-/canvas-darwin-arm64-0.1.22.tgz", + "integrity": "sha512-w6fcPbFPT8r3istcKBGKef11PBjAAQPWj8/KqDdoui8/tzuE0QsSkcnq8OTjfECzflgagPweM824Ua8KC2v9XA==", + "optional": true + }, + "@napi-rs/canvas-darwin-x64": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-x64/-/canvas-darwin-x64-0.1.22.tgz", + "integrity": "sha512-qgm9bIAZ408xFmB8L+7AcK2onii10wUUEJzKr6+Xi6CvXRCcGC2Mu3qHKTaRiV3OCPzS4RxGyXC05fahhRqRLQ==", + "optional": true + }, + "@napi-rs/canvas-linux-arm-gnueabihf": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm-gnueabihf/-/canvas-linux-arm-gnueabihf-0.1.22.tgz", + "integrity": "sha512-FmsK7I3BZoq9DBOIDo/y/MrbCjNqEkaFCN+bMx2k87y8kILrJKAPKCgqXjrj6OW+zisd33kHruFPALA3GrLZIQ==", + "optional": true + }, + "@napi-rs/canvas-linux-arm64-gnu": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-gnu/-/canvas-linux-arm64-gnu-0.1.22.tgz", + "integrity": "sha512-/um5HVrR7mJsAj3tA39TzTANT+LfpBc2blA9isMtsjlgfGKQow4BZUzyQTAptJz/69MMElo4g9STaitBrDNbmQ==", + "optional": true + }, + "@napi-rs/canvas-linux-arm64-musl": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-musl/-/canvas-linux-arm64-musl-0.1.22.tgz", + "integrity": "sha512-Qz58HSP62fQvnKIy0z6NbIwf66WNQH0GWOMl+QwVWJR7SdxtmY4+gletBrNkBkZo5I6u8D1WcODLKRZSMn0MGA==", + "optional": true + }, + "@napi-rs/canvas-linux-x64-gnu": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-gnu/-/canvas-linux-x64-gnu-0.1.22.tgz", + "integrity": "sha512-S/Bgcc3088emN3M6wl5ql+luGSh+6UIGwsldFCS1m8/3cBTs/IsEY++w4ef7PB30x2ScbcEjQPXrAGpyIct1oA==", + "optional": true + }, + "@napi-rs/canvas-linux-x64-musl": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-musl/-/canvas-linux-x64-musl-0.1.22.tgz", + "integrity": "sha512-WaJyxWb9QvYlkrCdOCgYTnWCTNJD+9UmWoIurpV9+rb2YvGuhovF3EkpqtQKiQNb1+GkcQ2LNfcGD/d0YKdqxg==", + "optional": true + }, + "@napi-rs/canvas-win32-x64-msvc": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-x64-msvc/-/canvas-win32-x64-msvc-0.1.22.tgz", + "integrity": "sha512-6Gx4TCsoF3eAFlgD9q1fVE8ee+/AiQlKvZ+vXRFtdbyFkTYGDknm01M+xHJXssBG8BYPOsMZtNzFjM1r8hQagg==", + "optional": true + }, "@npmcli/fs": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", @@ -5384,6 +5623,11 @@ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.3.tgz", "integrity": "sha512-QvjkYpiD+dJJraRA8+dGAU4i7aBbb2s0S3jA45TFOvg2VgqvdCDd/3N6CqA8gluk1W91GLoXg5enMUx560QzuA==" }, + "undici": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.4.0.tgz", + "integrity": "sha512-A1SRXysDg7J+mVP46jF+9cKANw0kptqSFZ8tGyL+HBiv0K1spjxPX8Z4EGu+Eu6pjClJUBdnUPlxrOafR668/g==" + }, "unique-filename": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", diff --git a/package.json b/package.json index 45487fa..51529ee 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,10 @@ "dependencies": { "@discordjs/opus": "github:discordjs/opus", "@discordjs/voice": "^0.8.0", + "@napi-rs/canvas": "^0.1.22", "apt": "^0.0.2", "axios": "^0.27.2", + "canvas": "^2.9.1", "cheerio": "^1.0.0-rc.10", "discord-reply": "^0.1.2", "discord.js": "^13.6.0", @@ -20,6 +22,7 @@ "sequelize": "^6.19.0", "sqlite3": "^5.0.3", "sudo": "^1.0.3", + "undici": "^5.4.0", "youtube-mp3-downloader": "^0.7.10", "ytdl-core": "^4.11.0", "ytdl-core-discord": "^1.3.1"