From 3d15fdd663c804b5b136ae82a44d4f2bf2f0e44a Mon Sep 17 00:00:00 2001 From: Guus van Meerveld Date: Sun, 28 Jun 2020 14:13:27 +0200 Subject: [PATCH] First commit --- .gitignore | 2 + commands/bot/uptime.js | 19 ++++ commands/clash/clan.js | 226 ++++++++++++++++++++++++++++++++++++++ commands/clash/player.js | 177 +++++++++++++++++++++++++++++ database/clanstore.json | 7 ++ database/playerstore.json | 7 ++ index.js | 32 ++++++ js/functions.js | 87 +++++++++++++++ json/lists.json | 13 +++ package-lock.json | 187 +++++++++++++++++++++++++++++++ 10 files changed, 757 insertions(+) create mode 100644 .gitignore create mode 100644 commands/bot/uptime.js create mode 100644 commands/clash/clan.js create mode 100644 commands/clash/player.js create mode 100644 database/clanstore.json create mode 100644 database/playerstore.json create mode 100644 index.js create mode 100644 js/functions.js create mode 100644 json/lists.json create mode 100644 package-lock.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6253b8f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +json/config.json \ No newline at end of file diff --git a/commands/bot/uptime.js b/commands/bot/uptime.js new file mode 100644 index 0000000..bbe25bc --- /dev/null +++ b/commands/bot/uptime.js @@ -0,0 +1,19 @@ +const { Command } = require('discord.js-commando'); +const fun = require('../../js/functions.js'); +const boot = new Date(); + +module.exports = class uptimeCommand extends Command { + constructor(client) { + super(client, { + name: 'uptime', + aliases: ['u'], + group: 'bot', + memberName: 'uptime', + description: 'Get the bots uptime' + }); + } + + run(msg) { + msg.say(fun.unixDur(boot, true)) + } +} \ No newline at end of file diff --git a/commands/clash/clan.js b/commands/clash/clan.js new file mode 100644 index 0000000..469f523 --- /dev/null +++ b/commands/clash/clan.js @@ -0,0 +1,226 @@ +const { Command } = require('discord.js-commando'); +const { MessageEmbed } = require('discord.js'); +const fun = require('../../js/functions.js'); +const list = require('../../json/lists.json'); +const axios = require('axios'); + +const db = new (require('json-config-store'))({ + cwd: `${process.cwd()}/database`, + configName: 'clanstore.json' +}) + +module.exports = class clanCommand extends Command { + constructor(client) { + super(client, { + name: 'clan', + aliases: ['c', 'cl'], + group: 'clash', + memberName: 'clan', + description: 'Get stats about a clan', + argsPromptLimit: 0, + args: [ + { + key: 'method', + prompt: '', + type: 'string', + default: 'get' + }, + { + key: 'clanTag', + prompt: '', + type: 'string', + default: "default" + }, + ], + examples: ['.clan get #FFFFFFFF', '.clan members #FFFFFFFF'] + }); + + } + + run(msg, args) { + if (msg.guild && args.clanTag == "default" && db.has(`${msg.guild.id}.clanTag`)) { + args.clanTag = db.get(`${msg.guild.id}.clanTag`) + } + + const clanTag = args.clanTag.replace("#", "") || ""; + switch (args.method) { + case "get": + axios.get(`https://api.clashofclans.com/v1/clans/%23${clanTag}`) + .then(res => { + let response = res.data + var labels = 'Labels not set' + if (response.labels.length) { + labels = '' + response.labels.forEach(x => { + if (response.labels.indexOf(x) != response.labels.length - 1) labels += `${x.name} | ` + else labels += x.name + }) + } + + var clanLoc = "Location not set" + if (response.location) { + clanLoc = response.location.name + } + + msg.say({ + embed: { + title: `${response.name} | ${response.tag.toUpperCase()}`, + color: '#0099ff', + description: response.description, + thumbnail: { + url: response.badgeUrls.small, + }, + fields: [ + { + name: 'Labels:', + value: `${labels}` + }, + { + name: 'Requirements:', + value: `🏆 ${response.requiredTrophies}`, + inline: true + }, + { + name: 'Type:', + value: `${list.types[response.type]}`, + inline: true + }, + { + name: 'Location:', + value: `${clanLoc}`, + inline: true + }, + { + name: 'Trophies:', + value: `<:trophy:722016684935872522> ${response.clanPoints} | <:versustrophy:722016340503822347> ${response.clanVersusPoints} `, + inline: true + }, + { + name: 'War:', + value: `W: ${response.warWins} | L: ${response.warLosses || "Not public"}`, + inline: true + }, + { + name: 'Warlog:', + value: `Public warlog: ${response.isWarLogPublic ? "✅" : "❌"}`, + inline: true + }, + { + name: 'War league:', + value: `League: ${response.warLeague.name}`, + inline: true + } + ], + author: { + name: `Requested by: ${msg.author.username}`, + icon_url: `https://cdn.discordapp.com/avatars/${msg.author.id}/${msg.author.avatar}.jpg` + }, + footer: { + text: 'Bot by Xeeon#7590' + }, + timestamp: new Date() + } + }); + }).catch(() => msg.say("Could not find that clan.")); + break; + case "unlink": + if (db.has(`${msg.guild.id}`)) { + db.delete(`${msg.guild.id}`) + let embed = { + embed: { + title: "Succefully unlinked!", + color: "ededed", + description: `Unlinked ${msg.guild.name}!`, + author: { + name: `Requested by: ${msg.author.username}`, + icon_url: `https://cdn.discordapp.com/avatars/${msg.author.id}/${msg.author.avatar}.jpg` + }, + footer: { + text: 'Bot by Xeeon#7590' + }, + timestamp: new Date() + } + } + msg.say(embed) + } else { + msg.say("This server doesn't have any linked clans!") + } + break; + case "members": + axios.get(`https://api.clashofclans.com/v1/clans/%23${clanTag}`) + .then(res => { + let response = res.data + + let embed = new MessageEmbed() + .setTitle(`Showing members for ${response.name}`) + .setColor('#1d9e1b') + .setThumbnail(response.badgeUrls.small) + .setTimestamp() + .setAuthor(`Requested by ${msg.author.username}`, `https://cdn.discordapp.com/avatars/${msg.author.id}/${msg.author.avatar}.jpg`) + + fun.fieldCreator(embed, response.memberList, 0, "members") + + msg.say(embed) + .then(x => fun.addReaction(x, response.memberList, "members")) + }).catch(console.error) + break; + case "link": + if (msg.guild && msg.guild.id) { + if (msg.member.hasPermission("ADMINISTRATOR")) { + if (db.get(`${msg.guild.id}.clanTag`) == clanTag) { + let embed = { + embed: { + title: "Already linked!", + color: "ededed", + thumbnail: { + url: db.get(`${msg.guild.id}.clanBadge`) + }, + description: `${msg.guild.name} is linked to ${db.get(`${msg.guild.id}.clanName`)} #${clanTag.toUpperCase()}!`, + author: { + name: `Requested by: ${msg.author.username}`, + icon_url: `https://cdn.discordapp.com/avatars/${msg.author.id}/${msg.author.avatar}.jpg` + }, + footer: { + text: 'Bot by Xeeon#7590' + }, + timestamp: new Date() + } + } + msg.say(embed) + return + } + axios.get(`https://api.clashofclans.com/v1/clans/%23${clanTag}`) + .then(response => { + db.set(`${msg.guild.id}.clanTag`, clanTag) + db.set(`${msg.guild.id}.clanBadge`, response.data.badgeUrls.small) + db.set(`${msg.guild.id}.clanName`, response.data.name) + let embed = { + embed: { + title: "Succefully linked!", + color: "ededed", + thumbnail: { + url: response.data.badgeUrls.small + }, + description: `Linked ${msg.guild.name} to ${response.data.name} #${clanTag.toUpperCase()}!`, + author: { + name: `Requested by: ${msg.author.username}`, + icon_url: `https://cdn.discordapp.com/avatars/${msg.author.id}/${msg.author.avatar}.jpg` + }, + footer: { + text: 'Bot by Xeeon#7590' + }, + timestamp: new Date() + } + } + msg.say(embed) + }).catch(() => msg.say("An Error occured when reading that command. Please use .help for more information.")) + } else msg.say('You don\'t have the rights to execute this command!') + } else msg.say("You can't link a server here!") + break; + default: + msg.say("Invalid usage of command; use .help for further information.") + break; + } + + } +}; \ No newline at end of file diff --git a/commands/clash/player.js b/commands/clash/player.js new file mode 100644 index 0000000..bc112ae --- /dev/null +++ b/commands/clash/player.js @@ -0,0 +1,177 @@ +const { Command } = require('discord.js-commando'); +const axios = require('axios'); +const list = require('../../json/lists.json'); +const fun = require('../../js/functions.js'); +const { MessageEmbed } = require('discord.js'); + +const db = new (require('json-config-store'))({ + cwd: `${process.cwd()}/database`, + configName: 'playerstore.json' +}) + +module.exports = class playerCommand extends Command { + constructor(client) { + super(client, { + name: 'player', + aliases: ['p', 'pl'], + group: 'clash', + memberName: 'player', + description: 'Get a player\'s stats', + argsPromptLimit: 0, + args: [ + { + key: 'method', + prompt: '', + type: 'string', + default: 'get' + }, + { + key: 'playerTag', + prompt: '', + type: 'string', + default: 'default' + }, + ] + }); + } + + run(msg, args) { + if (args.playerTag == "default" && db.has(`${msg.author.id}.playerTag`)) { + args.playerTag = db.get(`${msg.author.id}.playerTag`) + } + const playerTag = args.playerTag.replace("#", "") || ""; + + switch (args.method) { + case "get": + axios.get(`https://api.clashofclans.com/v1/players/%23${playerTag}`) + .then(res => { + let response = res.data; + if (response.townHallWeaponLevel) var weapon = `(Wpn Lvl ${response.townHallWeaponLevel})` + else var weapon = "" + + let embed = new MessageEmbed() + .setTitle(`${response.name} | ${response.tag.toUpperCase()}`) + .setColor('#fcba03') + .setThumbnail(response.league.iconUrls.small) + .setDescription(`Experience level: ${response.expLevel}\nRole: ${list.roles[response.role]}`) + + .addField('Trophies:', `<:trophy:722016684935872522> ${response.trophies} | <:versustrophy:722016340503822347> ${response.versusTrophies}`) + .addField('Offense:', `Attack wins: ${response.attackWins} | Warstars: ${response.warStars}`) + response.legendStatistics ? embed.addField(`Best Season: ${response.legendStatistics.bestSeason.id}`, `Trophies: ${response.legendStatistics.bestSeason.trophies} | Rank: #${response.legendStatistics.bestSeason.rank}`) : "" + response.legendStatistics ? embed.addField(`Previous Season: ${response.legendStatistics.previousSeason.id}`, `Trophies: ${response.legendStatistics.previousSeason.trophies} | Rank: #${response.legendStatistics.previousSeason.rank}`) : "" + embed.addField('Town Halls:', `Home: Lvl ${response.townHallLevel} ${weapon} | Builder: Lvl ${response.builderHallLevel}`) + .addField('Clan:', `Name: ${response.clan.name || "Not in a clan"} | Tag: ${response.clan.tag || "None"}`) + .addField('Donations:', `Donated: ${response.donations} | Received: ${response.donationsReceived}`) + + .setAuthor(`Requested by: ${msg.author.username}`, `https://cdn.discordapp.com/avatars/${msg.author.id}/${msg.author.avatar}.jpg`) + .setFooter('Bot by Xeeon#7590') + .setTimestamp() + + msg.say(embed); + }).catch(() => msg.say("Could not find that player.")) + break; + + case "link": + if (db.get(`${msg.author.id}.playerTag`) == playerTag) { + let embed = { + embed: { + title: "Already linked!", + color: "ededed", + thumbnail: { + url: db.get(`${msg.author.id}.playerBadge`) + }, + description: `${msg.author.username} is linked to ${db.get(`${msg.author.id}.playerName`)} #${playerTag.toUpperCase()}!`, + author: { + name: `Requested by: ${msg.author.username}`, + icon_url: `https://cdn.discordapp.com/avatars/${msg.author.id}/${msg.author.avatar}.jpg` + }, + footer: { + text: 'Bot by Xeeon#7590' + }, + timestamp: new Date() + } + } + msg.say(embed) + return + } + + axios.get(`https://api.clashofclans.com/v1/players/%23${playerTag}`) + .then(response => { + db.set(`${msg.author.id}.playerTag`, playerTag) + db.set(`${msg.author.id}.playerBadge`, response.data.league.iconUrls.small) + db.set(`${msg.author.id}.playerName`, response.data.name) + let embed = { + embed: { + title: "Succefully linked!", + color: "ededed", + thumbnail: { + url: response.data.league.iconUrls.small + }, + description: `Linked ${msg.author.username} to ${response.data.name} #${playerTag.toUpperCase()}!`, + author: { + name: `Requested by: ${msg.author.username}`, + icon_url: `https://cdn.discordapp.com/avatars/${msg.author.id}/${msg.author.avatar}.jpg` + }, + footer: { + text: 'Bot by Xeeon#7590' + }, + timestamp: new Date() + } + } + msg.say(embed) + }).catch(() => msg.say("Could not find that player.")) + break; + + case "unlink": + if (db.has(`${msg.author.id}`)) { + db.delete(`${msg.author.id}`) + let embed = { + embed: { + title: "Succefully unlinked!", + color: "ededed", + description: `Unlinked ${msg.author.username}!`, + author: { + name: `Requested by: ${msg.author.username}`, + icon_url: `https://cdn.discordapp.com/avatars/${msg.author.id}/${msg.author.avatar}.jpg` + }, + footer: { + text: 'Bot by Xeeon#7590' + }, + timestamp: new Date() + } + } + msg.say(embed) + } else { + msg.say("You don't have any linked accounts!") + } + break; + case "achievements": + axios.get(`https://api.clashofclans.com/v1/players/%23${playerTag}`) + .then(res => { + var response = res.data + let completed = [] + response.achievements.forEach(x => { + if (x.value >= x.target) completed[completed.length] = x.name + }) + + let embed = new MessageEmbed() + .setTitle(`${response.name} | ${response.tag.toUpperCase()}`) + .setColor('#fcba03') + .setThumbnail(response.league.iconUrls.small) + .setDescription(`Achievements: ${completed.length}/${response.achievements.length}`) + + .setAuthor(`Requested by: ${msg.author.username}`, `https://cdn.discordapp.com/avatars/${msg.author.id}/${msg.author.avatar}.jpg`) + .setFooter('Bot by Xeeon#7590') + .setTimestamp() + fun.fieldCreator(embed, response.achievements, 0, "achievements") + msg.say(embed) + .then(x => fun.addReaction(x, response.achievements, "achievements")) + }) + break; + default: + msg.say("Invalid usage of command; use .help for further information.") + break; + } + } +} + diff --git a/database/clanstore.json b/database/clanstore.json new file mode 100644 index 0000000..75361a0 --- /dev/null +++ b/database/clanstore.json @@ -0,0 +1,7 @@ +{ + "433347979747786753": { + "clanTag": "9Y80JU8C", + "clanBadge": "https://api-assets.clashofclans.com/badges/70/lYW_zen4bRRQ94B0gmtUoE2dxMwi4aVZn3PEmw-EvG4.png", + "clanName": "Toothbrush" + } +} \ No newline at end of file diff --git a/database/playerstore.json b/database/playerstore.json new file mode 100644 index 0000000..1e85305 --- /dev/null +++ b/database/playerstore.json @@ -0,0 +1,7 @@ +{ + "306849399336861707": { + "playerTag": "9QYC2JG2", + "playerBadge": "https://api-assets.clashofclans.com/leagues/72/4wtS1stWZQ-1VJ5HaCuDPfdhTWjeZs_jPar_YPzK6Lg.png", + "playerName": "Xeeon" + } +} \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..2932bcc --- /dev/null +++ b/index.js @@ -0,0 +1,32 @@ +console.clear() + +const { CommandoClient } = require('discord.js-commando'); +const path = require('path'); +const axios = require('axios') +const config = require('./json/config.json'); + +axios.defaults.headers.Authorization = `Bearer ${config.authToken}` + +const client = new CommandoClient({ + commandPrefix: '.', + owner: '306849399336861707' +}); + +client.registry + .registerDefaultTypes() + .registerGroups([ + ['clash', 'Clash commands'], + ['bot', 'Bot commands'] + ]) + .registerDefaultGroups() + .registerDefaultCommands() + .registerCommandsIn(path.join(__dirname, 'commands')); + +client.once('ready', () => { + console.log(`Logged in as ${client.user.tag}!`); + client.user.setActivity('.help'); +}); + +client.on('error', console.error); + +client.login(config.discordToken); \ No newline at end of file diff --git a/js/functions.js b/js/functions.js new file mode 100644 index 0000000..3894cd9 --- /dev/null +++ b/js/functions.js @@ -0,0 +1,87 @@ +const list = require('../json/lists.json'); + +module.exports.unixDur=function(r,t){function a(h){return 1==h?0:1}function g(h){return t?h:""}var b=new Date(new Date-r),k=b.getFullYear()-1970,d=b.getMonth(),c=b.getDate()-1,e=b.getHours()-1,f=b.getMinutes();b=b.getSeconds();var l=["Second","Seconds"],m=["Minute","Minutes"],n=["Hour","Hours"],p=["Day","Days"],q=["Month","Months"],u=["Year","Years"];return 0==b&&1>f&&1>e&&1>c&&1>d?"Nu":1>f&&1>e&&1>c&&1>d?b+" "+l[a(b)]:1>e&&1>c&&1>d?f+" "+m[a(f)]+g(" and "+b+" "+l[a(b)]):1>c&&1>d?e+" "+n[a(e)]+g(", "+f+" "+m[a(f)]+" and "+b+" "+l[a(b)]):1>d?c+" "+p[a(c)]+g(", "+e+" "+n[a(e)]+" and "+f+" "+m[a(f)]):1>k?d+" "+q[a(d)]+g(", "+c+" "+p[a(c)]+" and "+e+" "+n[a(e)]):k+" "+u[a(k)]+g(", "+d+" "+q[a(d)]+" and "+c+" "+p[a(c)])}; + +module.exports.addReaction = (embedMsg, array, type) => { + const filter = (reaction, user) => ['⏪', '◀️', '▶️', '⏩'].includes(reaction.emoji.name) && !user.bot + + embedMsg.awaitReactions(filter, { time: 600000, errors: ['time'], max: 1 }) + .then(collected => { + const reaction = collected.first(); + var embed = embedMsg + embed.embeds.fields = "" + console.log(embed); + + + switch (reaction.emoji.name) { + case '⏪': + + module.exports.fieldCreator(embed, array, 0, type) + embedMsg.edit(embed) + break; + case '◀️': + // embedMsg.edit(fun.listEmbed(response, page - 1, msg)) + break; + case '▶️': + // embedMsg.edit(fun.listEmbed(response, page + 1, msg)) + break; + case '⏩': + module.exports.fieldCreator(embed, array, module.exports.arrGroups(array).length, type) + break; + } + module.exports.addReaction(embedMsg) + }) + .catch(console.error); + + (async () => { + await embedMsg.react('⏪') + await embedMsg.react('◀️') + await embedMsg.react('▶️') + await embedMsg.react('⏩') + })() + +} + +module.exports.fieldCreator = (embed, array, page, type) => { + module.exports.arrGroups(array, 5)[page].forEach(x => { + switch (type) { + case "achievements": + if (x.completionInfo) var info = x.completionInfo + else var info = "" + + embed.addFields({ + name: `Name: ${x.name}`, + value: `Objective: ${module.exports.format(x.info)} \nProgress: ${module.exports.format(x.value)}/${module.exports.format(x.target)} \n${module.exports.format(info)}` + }) + break; + + case "members": + embed.addFields({ + name: `${x.name} | ${x.tag}`, + value: `Role: ${list.roles[x.role]} \nLeague: ${x.league.name} | Trophies: ${x.trophies} \nDonated: ${x.donations} | Received: ${x.donationsReceived}` + }) + break; + } + }) + return embed +} + +module.exports.format = (n) => { + return n.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1.") +} + +module.exports.arrGroups = (array, size) => { + var result = []; + var pos = 0; + while (pos < array.length) { + result.push(array.slice(pos, pos + size)); + pos += size; + } + return result; +} + +function customAbs(number, arrLength) { + if (number < 0) return 0 + else if (number > arrLength - 1) return arrLength - 1 + else return number +} \ No newline at end of file diff --git a/json/lists.json b/json/lists.json new file mode 100644 index 0000000..6b364c3 --- /dev/null +++ b/json/lists.json @@ -0,0 +1,13 @@ +{ + "roles": { + "leader": "Leader", + "coLeader": "Co-Leader", + "admin": "Elder", + "member": "Member" + }, + "types": { + "inviteOnly": "Invite only", + "closed": "Closed", + "open": "Anyone can join" + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..6bf9708 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,187 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@discordjs/collection": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.5.tgz", + "integrity": "sha512-CU1q0UXQUpFNzNB7gufgoisDHP7n+T3tkqTsp3MNUkVJ5+hS3BCvME8uCXAUFlz+6T2FbTCu75A+yQ7HMKqRKw==" + }, + "@discordjs/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@discordjs/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-ZfFsbgEXW71Rw/6EtBdrP5VxBJy4dthyC0tpQKGKmYFImlmmrykO14Za+BiIVduwjte0jXEBlhSKf0MWbFp9Eg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "requires": { + "event-target-shim": "^5.0.0" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "requires": { + "follow-redirects": "1.5.10" + } + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "common-tags": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", + "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "discord.js": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-12.2.0.tgz", + "integrity": "sha512-Ueb/0SOsxXyqwvwFYFe0msMrGqH1OMqpp2Dpbplnlr4MzcRrFWwsBM9gKNZXPVBHWUKiQkwU8AihXBXIvTTSvg==", + "requires": { + "@discordjs/collection": "^0.1.5", + "@discordjs/form-data": "^3.0.1", + "abort-controller": "^3.0.0", + "node-fetch": "^2.6.0", + "prism-media": "^1.2.0", + "setimmediate": "^1.0.5", + "tweetnacl": "^1.0.3", + "ws": "^7.2.1" + } + }, + "discord.js-commando": { + "version": "github:discordjs/Commando#bdbd84e2a978322f3af12c21e729eb7b7cd4a3dc", + "from": "github:discordjs/Commando", + "requires": { + "common-tags": "^1.8.0", + "require-all": "^3.0.0" + } + }, + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "requires": { + "is-obj": "^1.0.0" + } + }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + }, + "json-config-store": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/json-config-store/-/json-config-store-0.0.1.tgz", + "integrity": "sha1-qhgF6bGVEdJz9NCwXQKBPAywTig=", + "requires": { + "dot-prop": "^4.1.0", + "mkdirp": "^0.5.1" + } + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "requires": { + "mime-db": "1.44.0" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node-fetch": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + }, + "prism-media": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.2.tgz", + "integrity": "sha512-I+nkWY212lJ500jLe4tN9tWO7nRiBAVdMv76P9kffZjYhw20raMlW1HSSvS+MLXC9MmbNZCazMrAr+5jEEgTuw==" + }, + "require-all": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/require-all/-/require-all-3.0.0.tgz", + "integrity": "sha1-Rz1JcEvjEBFc4ST3c4Ox69hnExI=" + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "ws": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", + "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==" + } + } +}