commit d2619420eff65e6bd4af2ff1d0225ea35f8db78b Author: root Date: Thu Aug 14 16:15:16 2025 +0200 yes diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..37d7e73 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +.env diff --git a/commands/cookies.js b/commands/cookies.js new file mode 100644 index 0000000..33428bf --- /dev/null +++ b/commands/cookies.js @@ -0,0 +1,312 @@ +// cookies.js β€” rewritten & rebalanced +const { MongoClient, ServerApiVersion } = require('mongodb'); +require('dotenv').config(); + +const cookieSchema = require("../schemas/cookieSchema"); // expected to support findOne, findOneAndUpdate, updateOne, find +const cooldownSchema = require("../schemas/cooldownSchema"); // expected to support findOne, findOneAndUpdate +const Discord = require('discord.js'); + +const URI = process.env.URI; +if (!URI) throw new Error("Missing process.env.URI for MongoDB"); + +// single client reused +const client = new MongoClient(URI, { + useNewUrlParser: true, + useUnifiedTopology: true, + serverApi: ServerApiVersion.v1 +}); +client.connect().catch(err => { + console.error("Mongo connect error:", err); +}); + +// util +const msToTime = (duration) => { + const ms = Math.floor((duration % 1000) / 100); + const s = Math.floor((duration / 1000) % 60); + const m = Math.floor((duration / (1000 * 60)) % 60); + const h = Math.floor((duration / (1000 * 60 * 60)) % 24); + const pad = n => (n < 10 ? "0" + n : "" + n); + return `${pad(h)}:${pad(m)}:${pad(s)}`; +}; + +const delay = ms => new Promise(r => setTimeout(r, ms)); + +// --- Helpers --- +async function getCookies(userId) { + const rec = await cookieSchema.findOne({ _id: userId }); + return rec && typeof rec.cookies === 'number' ? rec.cookies : 0; +} + +async function changeCookies(userId, delta, username = null) { + // upsert and set username if provided + const update = { $inc: { cookies: delta } }; + if (username) update.$set = { user: username }; + return cookieSchema.findOneAndUpdate( + { _id: userId }, + update, + { upsert: true, returnDocument: 'after' } + ); +} + +async function getCooldown(uniqueId) { + const rec = await cooldownSchema.findOne({ _id: uniqueId }); + return rec && rec.cooldown ? rec.cooldown : 0; +} + +async function setCooldown(uniqueId, command, subcommand, msTimestamp) { + await cooldownSchema.findOneAndUpdate( + { _id: uniqueId }, + { _id: uniqueId, command, subcommand, cooldown: msTimestamp }, + { upsert: true } + ); +} + +function cooldownId(guildId, userId, command, subcommand) { + return `${guildId}-${userId}-${command}-${subcommand}`; +} + +// --- Game logic & rebalances --- +// Notes about balancing: +// - Collect: 1..20 cookies (consistent reward); Abra (special user id) gets 1.5x. +// - Steal: +// * successChance = attacker / (attacker + defender), clamped to [0.10, 0.90] +// * steal amount: random 1..ceil(defender/4) +// * failure penalty: attacker loses random 1..ceil(attacker/6) (transferred to defender) +// - Cooldowns: collect = 1 hour, steal = 15 minutes + +const ABRA_ID = "378135175059603457"; // kept from original for bonus + +async function collect(interaction, user) { + const sub = interaction.options._subcommand; + const id = cooldownId(interaction.guildId, interaction.user.id, interaction.commandName, sub); + const now = Date.now(); + const existing = await getCooldown(id); + if (existing > now) { + return interaction.reply({ + content: `The batch is still cooking, come back in **${msToTime(existing - now)}**`, + ephemeral: true + }); + } + + // set cooldown (1 hour) + const cooldownUntil = now + 60 * 60 * 1000; + await setCooldown(id, interaction.commandName, sub, cooldownUntil); + + // balanced collect amount: 1..20 + let amount = Math.floor(Math.random() * 20) + 1; + if (user.id === ABRA_ID) amount = Math.ceil(amount * 1.5); + + // update DB + await changeCookies(user.id, amount, user.username); + + // playful responses (kept / adapted) + const collectResponses = (amount, user) => { + const s = amount === 1 ? 'Cookie' : 'Cookies'; + return [ + `${user}, I made you **${amount}** ${s} πŸͺ`, + `${user}, here's your **${amount}** ${s} πŸͺ I ate the rest, sorry >.<`, + `Only **${amount}** ${s} πŸͺ for you today ${user}... Abra stole the rest :c`, + `${user}, would you like a Glass of Milk with your **${amount}** ${s}? πŸͺ`, + `**${amount}** ${s} πŸͺ Careful, ${user}! They're still warm :3`, + `**${amount}** ${s} πŸͺ Best Batch yet!`, + `**${amount}** ${s} πŸͺ These, I bequeath unto thine own self upon this day. Thou must guard them safely.`, + `${user}, your **${amount}** ${s} πŸͺ are fresh out of the oven... try not to burn your tongue!`, + `${user}, I bribed the Cookie Monster to spare these **${amount}** ${s} πŸͺ just for you.`, + `${user}, Santa came early! You got **${amount}** ${s} πŸͺ (milk not included).`, + `${user}, your **${amount}** ${s} πŸͺ are artisanal, gluten-free, and slightly cursed.`, + `A wild baker appeared! They hand you **${amount}** ${s} πŸͺ`, + `${user}, Abra said these **${amount}** ${s} πŸͺ are "totally not stolen"... πŸ€”`, + `${user}, here’s your **${amount}** ${s} πŸͺ β€” watch out, they may be booby-trapped.` + ]; + }; + + + const responses = collectResponses(amount, user); + const i = Math.floor(Math.random() * responses.length); + return interaction.reply({ content: responses[i] }); + +} + +async function steal(interaction, user) { + const target = interaction.options.getUser('target'); + if (!target) { + return interaction.reply({ content: `Pick someone to steal from.`, ephemeral: true }); + } + if (target.id === user.id) { + return interaction.reply({ + content: `C'mon, don't embarrass yourself! We all know you couldn't do that, even if you tried.`, + ephemeral: true + }); + } + + // pull balances + const your = await getCookies(user.id); + const their = await getCookies(target.id); + + if (your <= 0) { + return interaction.reply({ content: `You need at least 1 Cookie to attempt a Robbery`, ephemeral: true }); + } + if (their <= 0) { + return interaction.reply({ content: `Shame on you! ${target.username} doesn't have any Cookies D:`, ephemeral: true }); + } + + // steal cooldown (15 minutes) + const sub = interaction.options._subcommand; + const id = cooldownId(interaction.guildId, interaction.user.id, interaction.commandName, sub); + const now = Date.now(); + const existing = await getCooldown(id); + const chaos = true // 50% Stela Chance Mode + + if (existing > now) { + return interaction.reply({ + content: `Hold up β€” try stealing again in **${msToTime(existing - now)}**`, + ephemeral: true + }); + } + await setCooldown(id, interaction.commandName, sub, now + 15 * 60 * 1000); + + // success chance and clamping + let successChance = your / (your + their); + if (isNaN(successChance) || !isFinite(successChance)) successChance = 0.2; + if (chaos) { + successChance = 0.5 + } else { + successChance = Math.max(0.10, Math.min(0.90, successChance)); + } + const success = Math.random() < successChance; + + if (success) { + const stealSuccessResponses = (amount, target) => { + const s = amount === 1 ? 'Cookie' : 'Cookies'; + return [ + `You've successfully stolen **${amount}** ${s} from **${target.username}**!`, + `Ninja mode: activated. You snatched **${amount}** ${s} from **${target.username}** without a crumb left behind.`, + `Abra taught you well β€” **${amount}** ${s} from **${target.username}** are now yours!`, + `Like a phantom in the night, you took **${amount}** ${s} from **${target.username}**.`, + `You just pulled the sweetest heist: **${amount}** ${s} from **${target.username}**!`, + `Mission complete. **${target.username}** is **${amount}** ${s} poorer, you are richer.`, + `You distracted **${target.username}** with a dance and swiped **${amount}** ${s}.`, + `Clean getaway! **${target.username}** won’t know about the missing **${amount}** ${s} until it’s too late.`, + `The Cookie Vault has been breached. **${amount}** ${s} taken from **${target.username}**.`, + `You emerged from the shadows with **${amount}** ${s} from **${target.username}**.` + ]; + }; + + const maxSteal = Math.max(1, Math.ceil(their / 4)); // steal up to ~25% of victim + let amount = Math.floor(Math.random() * maxSteal) + 1; + amount = Math.min(amount, their); + + // transfer + await Promise.all([ + changeCookies(user.id, amount, user.username), + changeCookies(target.id, -amount, target.username) + ]); + + const responses = stealSuccessResponses(amount, target); + const i = Math.floor(Math.random() * responses.length); + return interaction.reply({ content: `${responses[i]} (Chance: ${Math.round(successChance * 100, 2)}%)` }); + + } else { + const stealFailResponses = (penalty, target) => { + const s = penalty === 1 ? 'Cookie' : 'Cookies'; + return [ + `You were caught red-handed by **${target.username}** and lost **${penalty}** ${s} as a penalty!`, + `Fail! **${target.username}** caught you mid-bite β€” you dropped **${penalty}** ${s}.`, + `Not your best moment... You lost **${penalty}** ${s} to **${target.username}** in the struggle.`, + `Stealth level: 0. You handed **${penalty}** ${s} to **${target.username}** as an apology.`, + `The cookie jar was booby-trapped! You gave **${penalty}** ${s} to **${target.username}** while running away.`, + `Ouch. The guard dog barked, and now **${target.username}** has your **${penalty}** ${s}.`, + `You tripped over your own shoelace β€” **${target.username}** reclaimed **${penalty}** ${s}.`, + `Caught by the Cookie Police! **${penalty}** ${s} confiscated and given to **${target.username}**.`, + `Your pockets had holes... **${target.username}** picked up **${penalty}** ${s} you dropped.` + ]; + }; + + + // failure penalty: attacker loses a little (1..ceil(your/6)) to the victim + const maxPenalty = Math.max(1, Math.ceil(your / 6)); + const penalty = Math.min(your, Math.floor(Math.random() * maxPenalty) + 1); + + await Promise.all([ + changeCookies(user.id, -penalty, user.username), + changeCookies(target.id, +penalty, target.username) + ]); + + const responses = stealFailResponses(penalty, target); + const i = Math.floor(Math.random() * responses.length); + return interaction.reply({ content: `${responses[i]} (Chance: ${Math.round(successChance * 100, 2)}%)` }); + + } +} + +async function check(interaction, user) { + let target = interaction.options.getUser('target'); + if (!target) target = user; + + const cookies = await getCookies(target.id); + const mood = cookies === 0 ? 'πŸ˜”' : '😲'; + return interaction.reply({ content: `**${target.username}** has **${cookies}** Cookies! ${mood}` }); +} + +async function give(interaction, user) { + const target = interaction.options.getUser('target'); + const amount = interaction.options.getInteger('amount'); + + if (!target) return interaction.reply({ content: `You need to specify a target.`, ephemeral: true }); + if (target.id === user.id) return interaction.reply({ content: 'You cannot give yourself Cookies ._."', ephemeral: true }); + if (!Number.isInteger(amount) || amount < 1) { + return interaction.reply({ content: `**${user}** shared *checks notes* **${amount}** Cookie(s) with ${target}....wait a minute!!`, ephemeral: true }); + } + + const your = await getCookies(user.id); + if (your < amount) return interaction.reply({ content: `We don't run a charity here, get more Cookies!`, ephemeral: true }); + + await Promise.all([ + changeCookies(user.id, -amount, user.username), + changeCookies(target.id, +amount, target.username) + ]); + + // small delay to mimic previous behavior + await delay(200); + return interaction.reply({ content: `**${user}** shared **${amount}** Cookie(s) with ${target}` }); +} + +async function leader(interaction) { + const results = await cookieSchema.find().sort({ cookies: -1 }).limit(10); + let cookieSorted = ''; + results.forEach((r, i) => { + cookieSorted += `[${i + 1}] <@${r._id}> (${r.cookies})\n`; + }); + + const embed = new Discord.MessageEmbed() + .setColor(0x0099FF) + .setThumbnail(interaction.guild.iconURL()) + .setTimestamp() + .addFields({ name: `-Cookie Leaderboard-`, value: cookieSorted || 'No cookie data yet.' }); + + return interaction.reply({ embeds: [embed] }); +} + +module.exports = { + slash: true, + description: 'collect a cookie', + category: 'Misc', + options: [ + { name: "collect", description: "want some?", type: 1 }, + { name: "steal", description: "try your luck at a lala robbery!", type: 1, options: [{ name: "target", description: "someone", required: true, type: 6 }] }, + { name: "check", description: "check your cookie stash", type: 1, options: [{ name: "target", description: "someone", type: 6 }] }, + { name: "give", description: "share your cookies with someone", type: 1, options: [{ name: "target", description: "someone", required: true, type: 6 }, { name: "amount", description: "cookies", required: true, type: 4 }] }, + { name: "leader", description: "show Top 10 Cookie Clickers", type: 1 } + ], + callback: ({ interaction, user }) => { + const sub = interaction.options._subcommand; + switch (sub) { + case "collect": return collect(interaction, user); + case "steal": return steal(interaction, user); + case "check": return check(interaction, user); + case "give": return give(interaction, user); + case "leader": return leader(interaction); + default: return interaction.reply({ content: 'Unknown subcommand', ephemeral: true }); + } + } +}; diff --git a/commands/cookies.js.10082025.old b/commands/cookies.js.10082025.old new file mode 100644 index 0000000..81e093c --- /dev/null +++ b/commands/cookies.js.10082025.old @@ -0,0 +1,448 @@ +const { MongoClient, ServerApiVersion } = require('mongodb'); +require('dotenv').config(); +const uri = process.env.URI +const cookieSchema = require("../schemas/cookieSchema") +const cooldownSchema = require("../schemas/cooldownSchema") +const delay = ms => new Promise(resolve => setTimeout(resolve, ms)) +const Discord = require('discord.js') +const client = new MongoClient(uri, { + useNewUrlParser: true, + useUnifiedTopology: true, + serverApi: ServerApiVersion.v1 +}); +function msToTime(duration) { + var milliseconds = parseInt((duration % 1000) / 100), + seconds = Math.floor((duration / 1000) % 60), + minutes = Math.floor((duration / (1000 * 60)) % 60), + hours = Math.floor((duration / (1000 * 60 * 60)) % 24); + + hours = (hours < 10) ? "0" + hours : hours; + minutes = (minutes < 10) ? "0" + minutes : minutes; + seconds = (seconds < 10) ? "0" + seconds : seconds; + + return hours + ":" + minutes + ":" + seconds; +} +async function collect(interaction, user) { + client.connect(async (err, db) => { + var dbo = db.db('test') + let id = `${interaction.guildId}-${interaction.user.id}-${interaction.commandName}-${interaction.options._subcommand}` + dbo.collection('cooldowns').findOne({ + _id: id + }, async function (err, results) { + let now = Date.now() + let time = now + 3600000 // plus one hour in ms + if (results) { + if (results.cooldown > now) { + time = new Date(results.cooldown).toUTCString() + return interaction.reply({ + content: `The batch is still cooking, come back in **${msToTime(results.cooldown - now)}**`, + ephemeral: true + }) + } + } + addCooldown(interaction.user.id, interaction.guildId, interaction.commandName, interaction.options._subcommand, time) + + + var amount = Math.floor(Math.random() * 30) + //random amount between 1 and 29 + if (user.id == "378135175059603457") { + //Abra Bonus + amount = Math.ceil(amount * 1.5) + } + + var responses = [ + `${user}, I made you **${amount}** ${amount == 1?`Cookie`: `Cookies`} πŸͺ `, + `${user}, Here's your **${amount}** ${amount == 1?`Cookie`: `Cookies`} πŸͺ I ate the rest, sorry >.<`, + `Only **${amount}** ${amount == 1?`Cookie`: `Cookies`} πŸͺ for you today ${user}... Abra stole the rest :c`, + `${user}, would you like a Glass of Milk with your **${amount}** ${amount == 1?`Cookie`: `Cookies`}? πŸͺ `, + `**${amount}** ${amount == 1?`Cookie`: `Cookies`} πŸͺ Careful, ${user}! They're still warm :3`, + `**${amount}** ${amount == 1?`Cookie`: `Cookies`} πŸͺ Best Batch yet!`, + `**${amount}** ${amount == 1?`Cookie`: `Cookies`} πŸͺ These, I bequeath unto thine own self upon this day. Thou must guard them safely.`, + ] + + await cookieSchema.findOneAndUpdate({ + _id: user.id + }, { + _id: user.id, + user: user.username, + $inc: { cookies: +amount } + }, { + upsert: true + }) + + if(amount === 0){ + interaction.reply({ + content: `${user}, someone ate all your Cookies already D:` + }) + } else { + var i = Math.floor(Math.random() * responses.length) + interaction.reply({ + content: responses[i] + }) + } + // choose response + }) + }) +} +/* +function steal(interaction, user) { + client.connect(async (err, db) => { + if (err) throw err; + let target = interaction.options.getUser('target') + let dbo = db.db("test") + + if (target.id == user.id) { + return interaction.reply({ + content: `C'mon, don't embarass yourself! We all know you couldn't do that, even if you tried.`, + ephemeral: true, + }) + } + + // get your amount of cookies + let your = await dbo.collection('cookies').findOne({ + _id: user.id + }) + // get their amount of cookies + let their = await dbo.collection('cookies').findOne({ + _id: target.id + }) + try { + if (!your.cookies) { + return interaction.reply({ + content: `You need at least 1 Cookie to attempt a Robbery`, + ephemeral: true, + }) + } + if (!their.cookies) { + return interaction.reply({ + content: `Shame on you! They don't even have any Cookies D:`, + ephemeral: true, + }) + } + } catch (error) { + return interaction.reply({ + content: `How awkward...I don't know some of you!`, + ephemeral: true, + }) + } + let difficulty = [] + for (var i = 0; i < their.cookies; i++) { + if (i < your.cookies) { + difficulty.push(true) + } else { + difficulty.push(false) + } + } + let result = Math.floor(Math.random() * their.cookies) + 1 + let response + if (!difficulty[result]) { + // author lost + response = `You were unsuccessful at robbing **${target.username}** and lost your chance at **${result}** ${result == 1?`Cookie`: `Cookies`}! ` + if (your.cookies - result <= 0) { + result = your.cookies + response += `That's all your Cookies gone.` + } + result *= -1 + + } else { + //author won + response = `You've successfully stolen **${result { + cookieSorted += `[${i + 1}] <@${result._id}> (${result.cookies})\n` + i++; + }) + + var embed = new Discord.MessageEmbed() + .setColor(0x0099FF) + .setThumbnail(interaction.guild.iconURL()) + .setTimestamp() + .addFields({ name: `-Cookie Leaderboard-`, value: cookieSorted }) + + interaction.reply({ + embeds: [embed] + }) +} +module.exports = { + slash: true, + description: 'collect a cookie', + category: 'Misc', + options: [ + //collect + { + name: "collect", + description: "want some?", + type: 1 // SubCommand Type + }, + //steal + { + name: "steal", + description: "try your luck at a lala robbery!", + type: 1, // SubCommand Type + options: [ + { + name: "target", + description: "someone", + required: true, + type: 6 // User Type + } + ] + }, + //check + { + name: "check", + description: "check your cookie stash", + required: false, + type: 1, // SubCommand Type + options: [ + { + name: "target", + description: "someone", + type: 6 // User Type + } + ] + }, + //give + { + name: "give", + description: "share your cookies with someone", + required: false, + type: 1, // SubCommand Type + options: [ + { + name: "target", + description: "someone", + required: true, + type: 6 // User Type + }, { + name: "amount", + description: "cookies", + required: true, + type: 4 // Integer Type + } + ] + }, + //leader + { + name: "leader", + description: "show Top 10 Cookie Clickers", + type: 1, // SubCommand Type + }, + ], + callback: ({ interaction, user }) => { + switch (interaction.options._subcommand) { + case "collect": + collect(interaction, user) + break; + case "steal": + steal(interaction, user) + break; + case "check": + check(interaction, user) + break; + case "give": + give(interaction, user) + break; + case "leader": + leader(interaction) + break; + default: + break; + } + } +} diff --git a/commands/cookies.js.1008202502.old b/commands/cookies.js.1008202502.old new file mode 100644 index 0000000..adfc6df --- /dev/null +++ b/commands/cookies.js.1008202502.old @@ -0,0 +1,262 @@ +// cookies.js β€” rewritten & rebalanced +const { MongoClient, ServerApiVersion } = require('mongodb'); +require('dotenv').config(); + +const cookieSchema = require("../schemas/cookieSchema"); // expected to support findOne, findOneAndUpdate, updateOne, find +const cooldownSchema = require("../schemas/cooldownSchema"); // expected to support findOne, findOneAndUpdate +const Discord = require('discord.js'); + +const URI = process.env.URI; +if (!URI) throw new Error("Missing process.env.URI for MongoDB"); + +// single client reused +const client = new MongoClient(URI, { + useNewUrlParser: true, + useUnifiedTopology: true, + serverApi: ServerApiVersion.v1 +}); +client.connect().catch(err => { + console.error("Mongo connect error:", err); +}); + +// util +const msToTime = (duration) => { + const ms = Math.floor((duration % 1000) / 100); + const s = Math.floor((duration / 1000) % 60); + const m = Math.floor((duration / (1000 * 60)) % 60); + const h = Math.floor((duration / (1000 * 60 * 60)) % 24); + const pad = n => (n < 10 ? "0" + n : "" + n); + return `${pad(h)}:${pad(m)}:${pad(s)}`; +}; + +const delay = ms => new Promise(r => setTimeout(r, ms)); + +// --- Helpers --- +async function getCookies(userId) { + const rec = await cookieSchema.findOne({ _id: userId }); + return rec && typeof rec.cookies === 'number' ? rec.cookies : 0; +} + +async function changeCookies(userId, delta, username = null) { + // upsert and set username if provided + const update = { $inc: { cookies: delta } }; + if (username) update.$set = { user: username }; + return cookieSchema.findOneAndUpdate( + { _id: userId }, + update, + { upsert: true, returnDocument: 'after' } + ); +} + +async function getCooldown(uniqueId) { + const rec = await cooldownSchema.findOne({ _id: uniqueId }); + return rec && rec.cooldown ? rec.cooldown : 0; +} + +async function setCooldown(uniqueId, command, subcommand, msTimestamp) { + await cooldownSchema.findOneAndUpdate( + { _id: uniqueId }, + { _id: uniqueId, command, subcommand, cooldown: msTimestamp }, + { upsert: true } + ); +} + +function cooldownId(guildId, userId, command, subcommand) { + return `${guildId}-${userId}-${command}-${subcommand}`; +} + +// --- Game logic & rebalances --- +// Notes about balancing: +// - Collect: 1..20 cookies (consistent reward); Abra (special user id) gets 1.5x. +// - Steal: +// * successChance = attacker / (attacker + defender), clamped to [0.10, 0.90] +// * steal amount: random 1..ceil(defender/4) +// * failure penalty: attacker loses random 1..ceil(attacker/6) (transferred to defender) +// - Cooldowns: collect = 1 hour, steal = 15 minutes + +const ABRA_ID = "378135175059603457"; // kept from original for bonus + +async function collect(interaction, user) { + const sub = interaction.options._subcommand; + const id = cooldownId(interaction.guildId, interaction.user.id, interaction.commandName, sub); + const now = Date.now(); + const existing = await getCooldown(id); + if (existing > now) { + return interaction.reply({ + content: `The batch is still cooking, come back in **${msToTime(existing - now)}**`, + ephemeral: true + }); + } + + // set cooldown (1 hour) + const cooldownUntil = now + 60 * 60 * 1000; + await setCooldown(id, interaction.commandName, sub, cooldownUntil); + + // balanced collect amount: 1..20 + let amount = Math.floor(Math.random() * 20) + 1; + if (user.id === ABRA_ID) amount = Math.ceil(amount * 1.5); + + // update DB + await changeCookies(user.id, amount, user.username); + + // playful responses (kept / adapted) + const responses = [ + `${user}, I made you **${amount}** ${amount === 1 ? 'Cookie' : 'Cookies'} πŸͺ`, + `${user}, here's your **${amount}** ${amount === 1 ? 'Cookie' : 'Cookies'} πŸͺ I ate the rest, sorry >.<`, + `Only **${amount}** ${amount === 1 ? 'Cookie' : 'Cookies'} πŸͺ for you today ${user}... Abra stole the rest :c`, + `${user}, would you like a Glass of Milk with your **${amount}** ${amount === 1 ? 'Cookie' : 'Cookies'}? πŸͺ`, + `**${amount}** ${amount === 1 ? 'Cookie' : 'Cookies'} πŸͺ Careful, ${user}! They're still warm :3`, + `**${amount}** ${amount === 1 ? 'Cookie' : 'Cookies'} πŸͺ Best Batch yet!`, + `**${amount}** ${amount === 1 ? 'Cookie' : 'Cookies'} πŸͺ These, I bequeath unto thine own self upon this day. Thou must guard them safely.` + ]; + + const i = Math.floor(Math.random() * responses.length); + return interaction.reply({ content: responses[i] }); +} + +async function steal(interaction, user) { + const target = interaction.options.getUser('target'); + if (!target) { + return interaction.reply({ content: `Pick someone to steal from.`, ephemeral: true }); + } + if (target.id === user.id) { + return interaction.reply({ + content: `C'mon, don't embarrass yourself! We all know you couldn't do that, even if you tried.`, + ephemeral: true + }); + } + + // steal cooldown (15 minutes) + const sub = interaction.options._subcommand; + const id = cooldownId(interaction.guildId, interaction.user.id, interaction.commandName, sub); + const now = Date.now(); + const existing = await getCooldown(id); + if (existing > now) { + return interaction.reply({ + content: `Hold up β€” try stealing again in **${msToTime(existing - now)}**`, + ephemeral: true + }); + } + await setCooldown(id, interaction.commandName, sub, now + 15 * 60 * 1000); + + // pull balances + const your = await getCookies(user.id); + const their = await getCookies(target.id); + + if (your <= 0) { + return interaction.reply({ content: `You need at least 1 Cookie to attempt a Robbery`, ephemeral: true }); + } + if (their <= 0) { + return interaction.reply({ content: `Shame on you! ${target.username} doesn't have any Cookies D:`, ephemeral: true }); + } + + // success chance and clamping + let successChance = your / (your + their); + if (isNaN(successChance) || !isFinite(successChance)) successChance = 0.2; + successChance = Math.max(0.50, Math.min(0.90, successChance)); // made it 50% for chaos + + const success = Math.random() < successChance; + + if (success) { + const maxSteal = Math.max(1, Math.ceil(their / 4)); // steal up to ~25% of victim + let amount = Math.floor(Math.random() * maxSteal) + 1; + amount = Math.min(amount, their); + + // transfer + await Promise.all([ + changeCookies(user.id, amount, user.username), + changeCookies(target.id, -amount, target.username) + ]); + + const s = amount === 1 ? 'Cookie' : 'Cookies'; + return interaction.reply({ + content: `You've successfully stolen **${amount}** ${s} from **${target.username}**!` + }); + } else { + // failure penalty: attacker loses a little (1..ceil(your/6)) to the victim + const maxPenalty = Math.max(1, Math.ceil(your / 6)); + const penalty = Math.min(your, Math.floor(Math.random() * maxPenalty) + 1); + + await Promise.all([ + changeCookies(user.id, -penalty, user.username), + changeCookies(target.id, +penalty, target.username) + ]); + + const s = penalty === 1 ? 'Cookie' : 'Cookies'; + return interaction.reply({ + content: `You were unsuccessful at robbing **${target.username}** and lost **${penalty}** ${s} as a penalty!` + }); + } +} + +async function check(interaction, user) { + let target = interaction.options.getUser('target'); + if (!target) target = user; + + const cookies = await getCookies(target.id); + const mood = cookies === 0 ? 'πŸ˜”' : '😲'; + return interaction.reply({ content: `**${target.username}** has **${cookies}** Cookies! ${mood}` }); +} + +async function give(interaction, user) { + const target = interaction.options.getUser('target'); + const amount = interaction.options.getInteger('amount'); + + if (!target) return interaction.reply({ content: `You need to specify a target.`, ephemeral: true }); + if (target.id === user.id) return interaction.reply({ content: 'You cannot give yourself Cookies ._."', ephemeral: true }); + if (!Number.isInteger(amount) || amount < 1) { + return interaction.reply({ content: `**${user}** shared *checks notes* **${amount}** Cookie(s) with ${target}....wait a minute!!`, ephemeral: true }); + } + + const your = await getCookies(user.id); + if (your < amount) return interaction.reply({ content: `We don't run a charity here, get more Cookies!`, ephemeral: true }); + + await Promise.all([ + changeCookies(user.id, -amount, user.username), + changeCookies(target.id, +amount, target.username) + ]); + + // small delay to mimic previous behavior + await delay(200); + return interaction.reply({ content: `**${user}** shared **${amount}** Cookie(s) with ${target}` }); +} + +async function leader(interaction) { + const results = await cookieSchema.find().sort({ cookies: -1 }).limit(10); + let cookieSorted = ''; + results.forEach((r, i) => { + cookieSorted += `[${i + 1}] <@${r._id}> (${r.cookies})\n`; + }); + + const embed = new Discord.MessageEmbed() + .setColor(0x0099FF) + .setThumbnail(interaction.guild.iconURL()) + .setTimestamp() + .addFields({ name: `-Cookie Leaderboard-`, value: cookieSorted || 'No cookie data yet.' }); + + return interaction.reply({ embeds: [embed] }); +} + +module.exports = { + slash: true, + description: 'collect a cookie', + category: 'Misc', + options: [ + { name: "collect", description: "want some?", type: 1 }, + { name: "steal", description: "try your luck at a lala robbery!", type: 1, options: [{ name: "target", description: "someone", required: true, type: 6 }] }, + { name: "check", description: "check your cookie stash", type: 1, options: [{ name: "target", description: "someone", type: 6 }] }, + { name: "give", description: "share your cookies with someone", type: 1, options: [{ name: "target", description: "someone", required: true, type: 6 }, { name: "amount", description: "cookies", required: true, type: 4 }] }, + { name: "leader", description: "show Top 10 Cookie Clickers", type: 1 } + ], + callback: ({ interaction, user }) => { + const sub = interaction.options._subcommand; + switch (sub) { + case "collect": return collect(interaction, user); + case "steal": return steal(interaction, user); + case "check": return check(interaction, user); + case "give": return give(interaction, user); + case "leader": return leader(interaction); + default: return interaction.reply({ content: 'Unknown subcommand', ephemeral: true }); + } + } +}; diff --git a/commands/cookies.js.1008202503.old b/commands/cookies.js.1008202503.old new file mode 100644 index 0000000..c47e6d9 --- /dev/null +++ b/commands/cookies.js.1008202503.old @@ -0,0 +1,307 @@ +// cookies.js β€” rewritten & rebalanced +const { MongoClient, ServerApiVersion } = require('mongodb'); +require('dotenv').config(); + +const cookieSchema = require("../schemas/cookieSchema"); // expected to support findOne, findOneAndUpdate, updateOne, find +const cooldownSchema = require("../schemas/cooldownSchema"); // expected to support findOne, findOneAndUpdate +const Discord = require('discord.js'); + +const URI = process.env.URI; +if (!URI) throw new Error("Missing process.env.URI for MongoDB"); + +// single client reused +const client = new MongoClient(URI, { + useNewUrlParser: true, + useUnifiedTopology: true, + serverApi: ServerApiVersion.v1 +}); +client.connect().catch(err => { + console.error("Mongo connect error:", err); +}); + +// util +const msToTime = (duration) => { + const ms = Math.floor((duration % 1000) / 100); + const s = Math.floor((duration / 1000) % 60); + const m = Math.floor((duration / (1000 * 60)) % 60); + const h = Math.floor((duration / (1000 * 60 * 60)) % 24); + const pad = n => (n < 10 ? "0" + n : "" + n); + return `${pad(h)}:${pad(m)}:${pad(s)}`; +}; + +const delay = ms => new Promise(r => setTimeout(r, ms)); + +// --- Helpers --- +async function getCookies(userId) { + const rec = await cookieSchema.findOne({ _id: userId }); + return rec && typeof rec.cookies === 'number' ? rec.cookies : 0; +} + +async function changeCookies(userId, delta, username = null) { + // upsert and set username if provided + const update = { $inc: { cookies: delta } }; + if (username) update.$set = { user: username }; + return cookieSchema.findOneAndUpdate( + { _id: userId }, + update, + { upsert: true, returnDocument: 'after' } + ); +} + +async function getCooldown(uniqueId) { + const rec = await cooldownSchema.findOne({ _id: uniqueId }); + return rec && rec.cooldown ? rec.cooldown : 0; +} + +async function setCooldown(uniqueId, command, subcommand, msTimestamp) { + await cooldownSchema.findOneAndUpdate( + { _id: uniqueId }, + { _id: uniqueId, command, subcommand, cooldown: msTimestamp }, + { upsert: true } + ); +} + +function cooldownId(guildId, userId, command, subcommand) { + return `${guildId}-${userId}-${command}-${subcommand}`; +} + +// --- Game logic & rebalances --- +// Notes about balancing: +// - Collect: 1..20 cookies (consistent reward); Abra (special user id) gets 1.5x. +// - Steal: +// * successChance = attacker / (attacker + defender), clamped to [0.10, 0.90] +// * steal amount: random 1..ceil(defender/4) +// * failure penalty: attacker loses random 1..ceil(attacker/6) (transferred to defender) +// - Cooldowns: collect = 1 hour, steal = 15 minutes + +const ABRA_ID = "378135175059603457"; // kept from original for bonus + +async function collect(interaction, user) { + const sub = interaction.options._subcommand; + const id = cooldownId(interaction.guildId, interaction.user.id, interaction.commandName, sub); + const now = Date.now(); + const existing = await getCooldown(id); + if (existing > now) { + return interaction.reply({ + content: `The batch is still cooking, come back in **${msToTime(existing - now)}**`, + ephemeral: true + }); + } + + // set cooldown (1 hour) + const cooldownUntil = now + 60 * 60 * 1000; + await setCooldown(id, interaction.commandName, sub, cooldownUntil); + + // balanced collect amount: 1..20 + let amount = Math.floor(Math.random() * 20) + 1; + if (user.id === ABRA_ID) amount = Math.ceil(amount * 1.5); + + // update DB + await changeCookies(user.id, amount, user.username); + + // playful responses (kept / adapted) + const collectResponses = (amount, user) => { + const s = amount === 1 ? 'Cookie' : 'Cookies'; + return [ + `${user}, I made you **${amount}** ${s} πŸͺ`, + `${user}, here's your **${amount}** ${s} πŸͺ I ate the rest, sorry >.<`, + `Only **${amount}** ${s} πŸͺ for you today ${user}... Abra stole the rest :c`, + `${user}, would you like a Glass of Milk with your **${amount}** ${s}? πŸͺ`, + `**${amount}** ${s} πŸͺ Careful, ${user}! They're still warm :3`, + `**${amount}** ${s} πŸͺ Best Batch yet!`, + `**${amount}** ${s} πŸͺ These, I bequeath unto thine own self upon this day. Thou must guard them safely.`, + `${user}, your **${amount}** ${s} πŸͺ are fresh out of the oven... try not to burn your tongue!`, + `${user}, I bribed the Cookie Monster to spare these **${amount}** ${s} πŸͺ just for you.`, + `${user}, Santa came early! You got **${amount}** ${s} πŸͺ (milk not included).`, + `${user}, your **${amount}** ${s} πŸͺ are artisanal, gluten-free, and slightly cursed.`, + `A wild baker appeared! They hand you **${amount}** ${s} πŸͺ`, + `${user}, Abra said these **${amount}** ${s} πŸͺ are "totally not stolen"... πŸ€”`, + `${user}, here’s your **${amount}** ${s} πŸͺ β€” watch out, they may be booby-trapped.` + ]; + }; + + + const responses = collectResponses(amount, user); + const i = Math.floor(Math.random() * responses.length); + return interaction.reply({ content: responses[i] }); + +} + +async function steal(interaction, user) { + const target = interaction.options.getUser('target'); + if (!target) { + return interaction.reply({ content: `Pick someone to steal from.`, ephemeral: true }); + } + if (target.id === user.id) { + return interaction.reply({ + content: `C'mon, don't embarrass yourself! We all know you couldn't do that, even if you tried.`, + ephemeral: true + }); + } + + // steal cooldown (15 minutes) + const sub = interaction.options._subcommand; + const id = cooldownId(interaction.guildId, interaction.user.id, interaction.commandName, sub); + const now = Date.now(); + const existing = await getCooldown(id); + if (existing > now) { + return interaction.reply({ + content: `Hold up β€” try stealing again in **${msToTime(existing - now)}**`, + ephemeral: true + }); + } + await setCooldown(id, interaction.commandName, sub, now + 15 * 60 * 1000); + + // pull balances + const your = await getCookies(user.id); + const their = await getCookies(target.id); + + if (your <= 0) { + return interaction.reply({ content: `You need at least 1 Cookie to attempt a Robbery`, ephemeral: true }); + } + if (their <= 0) { + return interaction.reply({ content: `Shame on you! ${target.username} doesn't have any Cookies D:`, ephemeral: true }); + } + + // success chance and clamping + let successChance = your / (your + their); + if (isNaN(successChance) || !isFinite(successChance)) successChance = 0.2; + successChance = Math.max(0.10, Math.min(0.90, successChance)); + + const success = Math.random() < successChance; + + if (success) { + const stealSuccessResponses = (amount, target) => { + const s = amount === 1 ? 'Cookie' : 'Cookies'; + return [ + `You've successfully stolen **${amount}** ${s} from **${target.username}**!`, + `Ninja mode: activated. You snatched **${amount}** ${s} from **${target.username}** without a crumb left behind.`, + `Abra taught you well β€” **${amount}** ${s} from **${target.username}** are now yours!`, + `Like a phantom in the night, you took **${amount}** ${s} from **${target.username}**.`, + `You just pulled the sweetest heist: **${amount}** ${s} from **${target.username}**!`, + `Mission complete. **${target.username}** is **${amount}** ${s} poorer, you are richer.`, + `You distracted **${target.username}** with a dance and swiped **${amount}** ${s}.`, + `Clean getaway! **${target.username}** won’t know about the missing **${amount}** ${s} until it’s too late.`, + `The Cookie Vault has been breached. **${amount}** ${s} taken from **${target.username}**.`, + `You emerged from the shadows with **${amount}** ${s} from **${target.username}**.` + ]; + }; + + const maxSteal = Math.max(1, Math.ceil(their / 4)); // steal up to ~25% of victim + let amount = Math.floor(Math.random() * maxSteal) + 1; + amount = Math.min(amount, their); + + // transfer + await Promise.all([ + changeCookies(user.id, amount, user.username), + changeCookies(target.id, -amount, target.username) + ]); + + const responses = stealSuccessResponses(amount, target); + const i = Math.floor(Math.random() * responses.length); + return interaction.reply({ content: responses[i] }); + + } else { + const stealFailResponses = (penalty, target) => { + const s = penalty === 1 ? 'Cookie' : 'Cookies'; + return [ + `You were caught red-handed by **${target.username}** and lost **${penalty}** ${s} as a penalty!`, + `Fail! **${target.username}** caught you mid-bite β€” you dropped **${penalty}** ${s}.`, + `Not your best moment... You lost **${penalty}** ${s} to **${target.username}** in the struggle.`, + `Stealth level: 0. You handed **${penalty}** ${s} to **${target.username}** as an apology.`, + `The cookie jar was booby-trapped! You gave **${penalty}** ${s} to **${target.username}** while running away.`, + `Ouch. The guard dog barked, and now **${target.username}** has your **${penalty}** ${s}.`, + `You tripped over your own shoelace β€” **${target.username}** reclaimed **${penalty}** ${s}.`, + `Caught by the Cookie Police! **${penalty}** ${s} confiscated and given to **${target.username}**.`, + `Your pockets had holes... **${target.username}** picked up **${penalty}** ${s} you dropped.` + ]; + }; + + + // failure penalty: attacker loses a little (1..ceil(your/6)) to the victim + const maxPenalty = Math.max(1, Math.ceil(your / 6)); + const penalty = Math.min(your, Math.floor(Math.random() * maxPenalty) + 1); + + await Promise.all([ + changeCookies(user.id, -penalty, user.username), + changeCookies(target.id, +penalty, target.username) + ]); + + const responses = stealFailResponses(penalty, target); + const i = Math.floor(Math.random() * responses.length); + return interaction.reply({ content: responses[i] }); + + } +} + +async function check(interaction, user) { + let target = interaction.options.getUser('target'); + if (!target) target = user; + + const cookies = await getCookies(target.id); + const mood = cookies === 0 ? 'πŸ˜”' : '😲'; + return interaction.reply({ content: `**${target.username}** has **${cookies}** Cookies! ${mood}` }); +} + +async function give(interaction, user) { + const target = interaction.options.getUser('target'); + const amount = interaction.options.getInteger('amount'); + + if (!target) return interaction.reply({ content: `You need to specify a target.`, ephemeral: true }); + if (target.id === user.id) return interaction.reply({ content: 'You cannot give yourself Cookies ._."', ephemeral: true }); + if (!Number.isInteger(amount) || amount < 1) { + return interaction.reply({ content: `**${user}** shared *checks notes* **${amount}** Cookie(s) with ${target}....wait a minute!!`, ephemeral: true }); + } + + const your = await getCookies(user.id); + if (your < amount) return interaction.reply({ content: `We don't run a charity here, get more Cookies!`, ephemeral: true }); + + await Promise.all([ + changeCookies(user.id, -amount, user.username), + changeCookies(target.id, +amount, target.username) + ]); + + // small delay to mimic previous behavior + await delay(200); + return interaction.reply({ content: `**${user}** shared **${amount}** Cookie(s) with ${target}` }); +} + +async function leader(interaction) { + const results = await cookieSchema.find().sort({ cookies: -1 }).limit(10); + let cookieSorted = ''; + results.forEach((r, i) => { + cookieSorted += `[${i + 1}] <@${r._id}> (${r.cookies})\n`; + }); + + const embed = new Discord.MessageEmbed() + .setColor(0x0099FF) + .setThumbnail(interaction.guild.iconURL()) + .setTimestamp() + .addFields({ name: `-Cookie Leaderboard-`, value: cookieSorted || 'No cookie data yet.' }); + + return interaction.reply({ embeds: [embed] }); +} + +module.exports = { + slash: true, + description: 'collect a cookie', + category: 'Misc', + options: [ + { name: "collect", description: "want some?", type: 1 }, + { name: "steal", description: "try your luck at a lala robbery!", type: 1, options: [{ name: "target", description: "someone", required: true, type: 6 }] }, + { name: "check", description: "check your cookie stash", type: 1, options: [{ name: "target", description: "someone", type: 6 }] }, + { name: "give", description: "share your cookies with someone", type: 1, options: [{ name: "target", description: "someone", required: true, type: 6 }, { name: "amount", description: "cookies", required: true, type: 4 }] }, + { name: "leader", description: "show Top 10 Cookie Clickers", type: 1 } + ], + callback: ({ interaction, user }) => { + const sub = interaction.options._subcommand; + switch (sub) { + case "collect": return collect(interaction, user); + case "steal": return steal(interaction, user); + case "check": return check(interaction, user); + case "give": return give(interaction, user); + case "leader": return leader(interaction); + default: return interaction.reply({ content: 'Unknown subcommand', ephemeral: true }); + } + } +}; diff --git a/commands/cookies.js.save b/commands/cookies.js.save new file mode 100644 index 0000000..657c7eb --- /dev/null +++ b/commands/cookies.js.save @@ -0,0 +1,383 @@ +const { MongoClient, ServerApiVersion } = require('mongodb'); +require('dotenv').config(); +const uri = process.env.URI +const cookieSchema = require("../schemas/cookieSchema") +const cooldownSchema = require("../schemas/cooldownSchema") +const delay = ms => new Promise(resolve => setTimeout(resolve, ms)) +const Discord = require('discord.js') + +const client = new MongoClient(uri, { + useNewUrlParser: true, + useUnifiedTopology: true, + serverApi: ServerApiVersion.v1 +}); +function msToTime(duration) { + var milliseconds = parseInt((duration % 1000) / 100), + seconds = Math.floor((duration / 1000) % 60), + minutes = Math.floor((duration / (1000 * 60)) % 60), + hours = Math.floor((duration / (1000 * 60 * 60)) % 24); + + hours = (hours < 10) ? "0" + hours : hours; + minutes = (minutes < 10) ? "0" + minutes : minutes; + seconds = (seconds < 10) ? "0" + seconds : seconds; + + return hours + ":" + minutes + ":" + seconds; +} +async function collect(interaction, user) { + client.connect(async (err, db) => { + var dbo = db.db('test') + let id = `${interaction.guildId}-${interaction.user.id}-${interaction.commandName}-${interaction.options._subcommand}` + dbo.collection('cooldowns').findOne({ + _id: id + }, async function (err, results) { + let now = Date.now() + let time = now + 3600000 // plus one hour in ms + if (results) { + if (results.cooldown > now) { + time = new Date(results.cooldown).toUTCString() + return interaction.reply({ + content: `The batch is still cooking, come back in **${msToTime(results.cooldown - now)}**`, + ephemeral: true + }) + } + } + addCooldown(interaction.user.id, interaction.guildId, interaction.commandName, interaction.options._subcommand, time) + + + var ftext = [ + "I ate the rest, sorry >.<", + "Blame Abra", + "Would you like some Milk with that?", + "Careful! They're still warm :3", + "Best Batch yet!", + "These, I bequeath unto thine own self upon this day. Thou must guard them safely.", + "" + ] + var i = Math.floor(Math.random() * ftext.length) + //funny text at the end + + var amount = Math.floor(Math.random() * 30) + //random amount between 1 and 29 + if (user.id == "378135175059603457") { + //Abra Bonus + amount *= 1.25 + } + + await cookieSchema.findOneAndUpdate({ + _id: user.id + }, { + _id: user.id, + user: user.username, + $inc: { cookies: +amount } + }, { + upsert: true + }) + + var response = `<@${user.id}>, πŸͺ you collected ${amou*nt} cookies!! πŸͺ ${ftext[i]}` + + interaction.reply({ + content: response + }) + }) + }) +} +function steal(interaction, user) { + client.connect(async (err, db) => { + if (err) throw err; + let target = interaction.options.getUser('target') + let dbo = db.db("test") + + if (target.id == user.id) { + return interaction.reply({ + content: `C'mon, don't embarass yourself! We all know you couldn't do that, even if you tried.`, + ephemeral: true, + }) + } + + // get your amount of cookies + let your = await dbo.collection('cookies').findOne({ + _id: user.id + }) + // get their amount of cookies + let their = await dbo.collection('cookies').findOne({ + _id: target.id + }) + try { + if (!your.cookies) { + return interaction.reply({ + content: `You need at least 1 Cookie to attempt a Robbery`, + ephemeral: true, + }) + } + if (!their.cookies) { + return interaction.reply({ + content: `Shame on you! They don't even have any Cookies D:`, + ephemeral: true, + }) + } + } catch (error) { + return interaction.reply({ + content: `How awkward...I don't know some of you!`, + ephemeral: true, + }) + } + let difficulty = [] + for (var i = 0; i < their.cookies; i++) { + if (i < your.cookies) { + difficulty.push(false) + } else { + difficulty.push(true) + } + } + let result = Math.floor(Math.random() * their.cookies) + 1 + let response + if (!difficulty[result]) { + // author lost + response = `You were unsuccessful at robbing **${target.username}** and lost **${result}** Cookie(s)! ` + if (your.cookies - result <= 0) { + result = your.cookies + response += `That's all your Cookies gone.` + } + result *= -1 + + } else { + //author won + response = `You've successfully stolen **${result}** Cookie(s) from **${target.username}**! ` + if (their.cookies - result <= 0) { + result = their.cookies + response += `They're completely dry now.` + } + } + interaction.reply({ + content: response + }) + + //update author's cookies + await cookieSchema.findOneAndUpdate({ + _id: user.id + }, { + _id: user.id, + user: user.username, + $inc: { cookies: +result } //will decrease if it's +negativeInteger + }, { + upsert: true + }) + + await cookieSchema.findOneAndUpdate({ + _id: target.id + }, { + _id: target.id, + user: target.username, + $inc: { cookies: -result } //will decrease if it's +negativeInteger + }, { + upsert: true + }) + }) + + + +} +function check(interaction, user) { + + client.connect(async function (err, db) { + let target = interaction.options.getUser('target') + + if (!target) { + target = user + } + let response = `**${target.username}** has ` + let dbo = db.db("test") + dbo.collection("cookies").findOne({ + _id: target.id + }, function (err, results) { + let cookies + if (!results) { + cookies = 0 + response += `**${cookies}** Cookies! πŸ˜”` + } else { + cookies = results.cookies + response += `**${cookies}** Cookies! 😲` + } + interaction.reply({ + content: response + }) + }) + }) +} +async function give(interaction, user) { + client.connect(async function (err, db) { + let target = interaction.options.getUser('target') + let amount = interaction.options.getInteger('amount') + let dbo = db.db('test') + + //check if you have enough cookies + let your = await dbo.collection('cookies').findOne({ + _id: user.id + }) + + if (target.id == user.id) { + return interaction.reply({ + content: 'You cannot give yourself Cookies ._."' + }) + } + if (your.cookies < amount) { + return interaction.reply({ + content: `We don't run a charity here, get more Cookies!` + }) + } + if (amount < 1) { + return interaction.reply({ + content: `**${user}** shared *checks notes* **${amount}** Cookie(s) with ${target}....wait a minute!!`, + }) + } + + //update user's cookies + await cookieSchema.findOneAndUpdate({ + _id: user.id + }, { + _id: user.id, + user: user.username, + $inc: { cookies: -amount } + }, { + upsert: true + }) + + //update target's cookies + await cookieSchema.findOneAndUpdate({ + _id: target.id + }, { + _id: target.id, + user: target.username, + $inc: { cookies: +amount } + }, { + upsert: true + }) + await delay(200) + interaction.reply({ + content: `**${user}** shared **${amount}** Cookie(s) with ${target}` + }) + + }) +} +async function addCooldown(userId, guildId, command, subcommand, ms) { + let id = `${guildId}-${userId}-${command}-${subcommand}` + await cooldownSchema.findOneAndUpdate({ + _id: id + }, { + _id: id, + command: command, + subcommand: subcommand, + cooldown: ms + }, { + upsert: true + }) +} +async function leader(interaction) { + const results = await cookieSchema.find().sort({ + cookies: -1 + }).limit(10) + let cookieSorted = '' + let i = 0 + results.forEach((result) => { + cookieSorted += `[${i + 1}] <@${result._id}> (${result.cookies})\n` + i++; + }) + + var embed = new Discord.MessageEmbed() + .setColor(0x0099FF) + .setThumbnail(interaction.guild.iconURL()) + .setTimestamp() + .addFields({ name: `-Cookie Leaderboard-`, value: cookieSorted }) + + interaction.reply({ + embeds: [embed] + }) +} +module.exports = { + slash: true, + description: 'collect a cookie', + category: 'Misc', + options: [ + //collect + { + name: "collect", + description: "want some?", + type: 1 // SubCommand Type + }, + //steal + { + name: "steal", + description: "try your luck at a lala robbery!", + type: 1, // SubCommand Type + options: [ + { + name: "target", + description: "someone", + required: true, + type: 6 // User Type + } + ] + }, + //check + { + name: "check", + description: "check your cookie stash", + required: false, + type: 1, // SubCommand Type + options: [ + { + name: "target", + description: "someone", + type: 6 // User Type + } + ] + }, + //give + { + name: "give", + description: "share your cookies with someone", + required: false, + type: 1, // SubCommand Type + options: [ + { + name: "target", + description: "someone", + required: true, + type: 6 // User Type + }, { + name: "amount", + description: "cookies", + required: true, + type: 4 // Integer Type + } + ] + }, + //leader + { + name: "leader", + description: "show Top 10 Cookie Clickers", + type: 1, // SubCommand Type + }, + ], + callback: ({ interaction, user }) => { + switch (interaction.options._subcommand) { + case "collect": + collect(interaction, user) + break; + case "steal": + steal(interaction, user) + break; + case "check": + check(interaction, user) + break; + case "give": + give(interaction, user) + break; + case "leader": + leader(interaction) + break; + default: + break; + } + } +} diff --git a/commands/dontclickthis.js b/commands/dontclickthis.js new file mode 100644 index 0000000..423085b --- /dev/null +++ b/commands/dontclickthis.js @@ -0,0 +1,31 @@ +module.exports = { + slash: true, + description: 'surprise!', + category: 'meme', + options: [ + { + name: 'pwned', + description: "Told you not to click on this", + required: true, + type: 3, + choices: [ + { "name": 'never', "value": "never" }, + { "name": 'gonna', "value": "gonna" }, + { "name": 'give', "value": "give" }, + { "name": 'you', "value": "you" }, + { "name": 'up', "value": "up" }, + { "name": 'never', "value": "never" }, + { "name": 'gonna', "value": "gonna" }, + { "name": 'let', "value": "let" }, + { "name": 'you', "value": "you" }, + { "name": 'down', "value": "down" }, + ], + }, + ], + callback: async ({ interaction }) => { + interaction.reply({ + content: "https://www.youtube.com/watch?v=dQw4w9WgXcQ", + ephemeral: true, + }) + } +} \ No newline at end of file diff --git a/commands/random.js b/commands/random.js new file mode 100644 index 0000000..719f713 --- /dev/null +++ b/commands/random.js @@ -0,0 +1,209 @@ +const { MongoClient, ServerApiVersion } = require('mongodb'); +require('dotenv').config(); +const uri = process.env.URI +const delay = ms => new Promise(resolve => setTimeout(resolve, ms)) +const client = new MongoClient(uri, { + useNewUrlParser: true, + useUnifiedTopology: true, + serverApi: ServerApiVersion.v1 +}); +const expansions = new Map([ + ["ARR", { "min": 0, "max": 50 }], + ["HW", { "min": 51, "max": 60 }], + ["SB", { "min": 61, "max": 70 }], + ["ShB", { "min": 71, "max": 80 }], + ["EW", { "min": 81, "max": 90 }], + +]) + +async function getDutyData(interaction, database, user) { + var parameters = { + "type": interaction.options.getString('type'), + "min": interaction.options.getInteger('minlevel'), + "max": interaction.options.getInteger('maxlevel'), + "expansion": interaction.options.getString('expansion') + } + if (!parameters.type) { + //no type specified, randomizing... + database.listCollections().toArray(function (err, results) { + if (err) throw err; + let random = Math.floor(Math.random() * results.length) + parameters.type = results[random].name + }) + } + + if (parameters.expansion) { + //check if paramters are set correctly + if (!parameters.min) { + parameters.min = expansions.get(parameters.expansion).min + } + if (parameters.min < expansions.get(parameters.expansion).min) { + return console.log("mismatch min level and expansion") + } + + if (!parameters.max) { + parameters.max = expansions.get(parameters.expansion).max + } + if (parameters.max > expansions.get(parameters.expansion).max) { + return console.log("mismatch max level and expansion") + } + } else { + if (!parameters.min) { parameters.min = 0 } + if (!parameters.max) { parameters.max = 90 } + } + + if (parameters.type == 'pvp') { + parameters.expansion = 'ARR' + parameters.min = expansions.get(parameters.expansion).min + parameters.max = expansions.get(parameters.expansion).max + } + + await delay(500) //wait for updates + database.collection(parameters.type).find({ + level: { '$gte': parameters.min, '$lte': parameters.max } + }).toArray(async function (err, results2) { + let random = Math.floor(Math.random() * results2.length) + try { + let duty = results2[random] + let reply = `<@${user.id}>, Thou shalt playeth...${duty.name} [Level: ${duty.level}, Type: ${parameters.type}` + if (duty.expansion) { + reply += `, Expansion: ${duty.expansion}]` + } else { + reply += ']' + } + + interaction.reply({ + content: reply + }) + } catch (error) { + interaction.reply({ + content: `WAA!! (Impossible Combination found)` + }) + } + }) +} +async function getClassData(interaction, database, user) { + var collection = interaction.options.getString('type') + if (!collection) { + //no type specified + database.listCollections().toArray(function (err, cResults) { + let rdm = Math.floor(Math.random() * cResults.length) + collection = cResults[rdm].name + }) + } + + await delay(200) //wait for database.listCollections() + + database.collection(collection).find({}).toArray(async function (err, results) { + if (err) throw err; + var response + try { + let rdm = Math.floor(Math.random() * results.length) + response = `<@${user.id}>, Thou shalt playeth...${results[rdm].job}` + } catch (error) { + response = 'Invalid Type specified!' + } + interaction.reply({ + content: response, + }) + }) +} +module.exports = { + category: 'Random', + description: 'randomized helper', // Required for slash commands + slash: true, // Create both a slash and legacy command + options: [ + { + name: "duty", + type: 1, + description: "random duty", + options: [ + { + name: 'type', + description: 'what kind of duty would you like?', + required: false, + type: 3, + choices: [ + { "name": 'Dungeons', "value": "dungeons" }, + { "name": 'Guildhests', "value": "guildhests" }, + { "name": 'PvP', "value": "pvp" }, + { "name": 'Normal Raids', "value": "nraids" }, + { "name": 'Alliance Raids', "value": "araids" }, + { "name": 'Trials', "value": "trials" }, + { "name": 'Extreme', "value": "extreme" }, + { "name": 'Savage', "value": "savage" }, + { "name": 'Ultimates', "value": "ultimates" }, + { "name": 'Roulettes', "value": "roulettes" }, + ], + }, + { + name: 'minlevel', + description: 'Start of Level Range, assuming 0 if not specified', + required: false, + type: 4, + }, + { + name: 'maxlevel', + description: 'End of Level Range, assuming 90 if not specified', + required: false, + type: 4, + }, + { + name: 'expansion', + description: 'which expansion would you like?', + required: false, + type: 3, + choices: [ + { "name": 'A Realm Reborn', "value": "ARR" }, + { "name": 'Heavensward', "value": "HW" }, + { "name": 'Stormblood', "value": "SB" }, + { "name": 'Shadowbringers', "value": "ShB" }, + { "name": 'Endwalker', "value": "EW" }, + ], + } + ], + }, + { + name: "class", + type: 1, + description: "random class", + options: [ + { + name: 'type', + description: 'specify class', + required: false, + type: 3, + choices: [ + { "name": 'Healer', "value": "healer" }, + { "name": 'Tank', "value": "tank" }, + { "name": 'Melee', "value": "melee" }, + { "name": 'Ranged', "value": "ranged" }, + { "name": 'Caster', "value": "caster" }, + ], + } + ] + } + + ], + callback: ({ interaction, user }) => { + switch (interaction.options._subcommand) { + case "duty": + client.connect(function (err, db) { + if (err) throw err; + + var dbDuties = db.db("Duties") + getDutyData(interaction, dbDuties, user) + }) + break; + case "class": + client.connect(async function (err, db) { + if (err) throw err; + + var dbClasses = db.db("Classes") + getClassData(interaction, dbClasses, user) + }) + default: + break; + } + }, +} \ No newline at end of file diff --git a/commands/sus.js b/commands/sus.js new file mode 100644 index 0000000..426138b --- /dev/null +++ b/commands/sus.js @@ -0,0 +1,10 @@ +module.exports = { + slash: true, + description: 'sussy baka', + category: 'meme', + callback: async ({ interaction }) => { + interaction.reply({ + content: "࢞" + }) + } +} diff --git a/commands/template.txt b/commands/template.txt new file mode 100644 index 0000000..7eed431 --- /dev/null +++ b/commands/template.txt @@ -0,0 +1,29 @@ +module.exports = { + slash: true, + description: '', + category: '', + options: [ + { + name: 'victim', + description: 'pick anyone >:D', + required: true, + type: 9, + options: [ + { + name: 'type', + description: 'what kind of duty would you like?', + required: false, + type: 3, //String + choices: [ + { "name": 'choice', "value": "value" }, + ], + autocomplete: true + }, + ], + + }, + ], + callback: async ({ interaction }) => { + + } +} \ No newline at end of file diff --git a/commands/waa.js b/commands/waa.js new file mode 100644 index 0000000..a24085e --- /dev/null +++ b/commands/waa.js @@ -0,0 +1,26 @@ +module.exports = { + slash: true, + description: 'waa! at someone', + category: 'Misc', + cooldown: '3h', + options: [ + { + name: 'victim', + description: 'pick anyone >:D', + required: true, + type: 9, + }, + ], + callback: async ({ interaction, args, client }) => { + var reply = 'waa!' + + const member = client.users.cache.get(args[0]); + if(args[0]){ + reply+= ` <@${member.id}>` + } + interaction.reply({ + content: reply, + tts: true + }) + } +} \ No newline at end of file diff --git a/duties/araids.json b/duties/araids.json new file mode 100644 index 0000000..50dc84f --- /dev/null +++ b/duties/araids.json @@ -0,0 +1,15 @@ +[ + {"name": "The Labyrinth of the Ancients", "level": 50, "expansion": "ARR"}, + {"name": "Syrcus Tower", "level": 50, "expansion": "ARR"}, + {"name": "The World of Darkness", "level": 50, "expansion": "ARR"}, + {"name": "The Void Ark", "level": 60, "expansion": "HW"}, + {"name": "The Weeping City of Mhach", "level": 60, "expansion": "HW"}, + {"name": "Dun Scaith", "level": 60, "expansion": "HW"}, + {"name": "The Royal City of Rabanastre", "level": 70, "expansion": "SB"}, + {"name": "The Ridorana Lighthouse", "level": 70, "expansion": "SB"}, + {"name": "The Orbonne Monastery", "level": 70, "expansion": "SB"}, + {"name": "The Copied Factory", "level": 80, "expansion": "ShB"}, + {"name": "The Puppets' Bunker", "level": 80, "expansion": "ShB"}, + {"name": "The Tower at Paradigm's Breach", "level": 80, "expansion": "ShB"}, + {"name": "Aglaia", "level": 90, "expansion": "EW"} +] \ No newline at end of file diff --git a/duties/dungeons.json b/duties/dungeons.json new file mode 100644 index 0000000..376fddc --- /dev/null +++ b/duties/dungeons.json @@ -0,0 +1,88 @@ +[ + {"name": "Sastasha", "level": 15, "expansion": "ARR"}, + {"name": "The Tam-Tara Deepcroft", "level": 16, "expansion": "ARR"}, + {"name": "Copperbell Mines", "level": 17, "expansion": "ARR"}, + {"name": "Halatali", "level": 20, "expansion": "ARR"}, + {"name": "The Thousand Maws of Toto-Rak", "level": 24, "expansion": "ARR"}, + {"name": "Haukke Manor", "level": 28, "expansion": "ARR"}, + {"name": "Brayflox's Longstop", "level": 32, "expansion": "ARR"}, + {"name": "The Sunken Temple of Quarn", "level": 35, "expansion": "ARR"}, + {"name": "Cutter's Cry", "level": 41, "expansion": "ARR"}, + {"name": "The Stone Vigil", "level": 44, "expansion": "ARR"}, + {"name": "Dzemael Darkhold", "level": 47, "expansion": "ARR"}, + {"name": "The Aurum Vale", "level": 50, "expansion": "ARR"}, + {"name": "The Wanderer's Palace", "level": 50, "expansion": "ARR"}, + {"name": "Castrum Meridianum", "level": 50, "expansion": "ARR"}, + {"name": "The Praetorium", "level": 50, "expansion": "ARR"}, + {"name": "Amdapor Keep", "level": 50, "expansion": "ARR"}, + {"name": "Pharos Sirius", "level": 50, "expansion": "ARR"}, + {"name": "Copperbell Mines (Hard)", "level": 50, "expansion": "ARR"}, + {"name": "Haukke Manor (Hard)", "level": 50, "expansion": "ARR"}, + {"name": "The Lost City of Amdapor", "level": 50, "expansion": "ARR"}, + {"name": "Halatali (Hard)", "level": 50, "expansion": "ARR"}, + {"name": "Brayflox's Longstop (Hard)", "level": 50, "expansion": "ARR"}, + {"name": "Hullbreaker Isle", "level": 50, "expansion": "ARR"}, + {"name": "The Tam-Tara Deepcroft (Hard)", "level": 50, "expansion": "ARR"}, + {"name": "The Stone Vigil (Hard)", "level": 50, "expansion": "ARR"}, + {"name": "Snowcloak", "level": 50, "expansion": "ARR"}, + {"name": "Sastasha (Hard)", "level": 50, "expansion": "ARR"}, + {"name": "The Sunken Temple of Quarn (Hard)", "level": 50, "expansion": "ARR"}, + {"name": "The Keeper of the Lake", "level": 50, "expansion": "ARR"}, + {"name": "The Wanderer's Palace (Hard)", "level": 50, "expansion": "ARR"}, + {"name": "Amdapor Keep (Hard)", "level": 50, "expansion": "ARR"}, + {"name": "The Dusk Vigil", "level": 51, "expansion": "HW"}, + {"name": "Sohm Al", "level": 53, "expansion": "HW"}, + {"name": "The Aery", "level": 55, "expansion": "HW"}, + {"name": "The Vault", "level": 57, "expansion": "HW"}, + {"name": "The Great Gubal Library", "level": 59, "expansion": "HW"}, + {"name": "The Aetherochemical Research Facility", "level": 60, "expansion": "HW"}, + {"name": "Neverreap", "level": 60, "expansion": "HW"}, + {"name": "The Fractal Continuum", "level": 60, "expansion": "HW"}, + {"name": "Saint Mocianne's Arboretum", "level": 60, "expansion": "HW"}, + {"name": "Pharos Sirius (Hard)", "level": 60, "expansion": "HW"}, + {"name": "The Antitower", "level": 60, "expansion": "HW"}, + {"name": "The Lost City of Amdapor (Hard)", "level": 60, "expansion": "HW"}, + {"name": "Sohr Khai", "level": 60, "expansion": "HW"}, + {"name": "Hullbreaker Isle (Hard)", "level": 60, "expansion": "HW"}, + {"name": "Xelphatol", "level": 60, "expansion": "HW"}, + {"name": "The Great Gubal Library (Hard)", "level": 60, "expansion": "HW"}, + {"name": "Baelsar's Wall", "level": 60, "expansion": "HW"}, + {"name": "Sohm Al (Hard)", "level": 60, "expansion": "HW"}, + {"name": "The Sirensong Sea", "level": 61, "expansion": "SB"}, + {"name": "Shisui of the Violet Tides", "level": 63, "expansion": "SB"}, + {"name": "Bardam's Mettle", "level": 65, "expansion": "SB"}, + {"name": "Doma Castle", "level": 67, "expansion": "SB"}, + {"name": "Castrum Abania", "level": 69, "expansion": "SB"}, + {"name": "Ala Mhigo", "level": 70, "expansion": "SB"}, + {"name": "Kugane Castle", "level": 70, "expansion": "SB"}, + {"name": "The Temple of the Fist", "level": 70, "expansion": "SB"}, + {"name": "The Drowned City of Skalla", "level": 70, "expansion": "SB"}, + {"name": "Hell's Lid", "level": 70, "expansion": "SB"}, + {"name": "The Fractal Continuum (Hard)", "level": 70, "expansion": "SB"}, + {"name": "The Swallow's Compass", "level": 70, "expansion": "SB"}, + {"name": "The Burn", "level": 70, "expansion": "SB"}, + {"name": "Saint Mocianne's Arboretum (Hard)", "level": 70, "expansion": "SB"}, + {"name": "The Ghimlyt Dark", "level": 70, "expansion": "SB"}, + {"name": "Holminster", "level": 71, "expansion": "ShB"}, + {"name": "Dohn Mheg", "level": 73, "expansion": "ShB"}, + {"name": "The Qitana Ravel", "level": 75, "expansion": "ShB"}, + {"name": "Malikah's Well", "level": 77, "expansion": "ShB"}, + {"name": "Mt. Gulg", "level": 79, "expansion": "ShB"}, + {"name": "Amaurot", "level": 80, "expansion": "ShB"}, + {"name": "The Twinning", "level": 80, "expansion": "ShB"}, + {"name": "Akadaemia Anyder", "level": 80, "expansion": "ShB"}, + {"name": "The Grand Cosmos", "level": 80, "expansion": "ShB"}, + {"name": "The Heroes' Gauntlet", "level": 80, "expansion": "ShB"}, + {"name": "Matoya's Relict", "level": 80, "expansion": "ShB"}, + {"name": "Paglth'an", "level": 80, "expansion": "ShB"}, + {"name": "The Tower of Zot", "level": 81, "expansion": "EW"}, + {"name": "The Tower of Babel", "level": 83, "expansion": "EW"}, + {"name": "Vanaspati", "level": 85, "expansion": "EW"}, + {"name": "Ktisis Hyperboreia", "level": 87, "expansion": "EW"}, + {"name": "The Aitiascope", "level": 89, "expansion": "EW"}, + {"name": "The Dead Ends", "level": 90, "expansion": "EW"}, + {"name": "Smileton", "level": 90, "expansion": "EW"}, + {"name": "The Stigma Dreamscape", "level": 90, "expansion": "EW"}, + {"name": "Alzadaal's Legacy", "level": 90, "expansion": "EW"}, + {"name": "The Fell Court of Troia", "level": 90, "expansion": "EW"} +] \ No newline at end of file diff --git a/duties/extreme.json b/duties/extreme.json new file mode 100644 index 0000000..37844b7 --- /dev/null +++ b/duties/extreme.json @@ -0,0 +1,37 @@ +[ + {"name": "The Howling Eye (Extreme)", "level": 50, "expansion": "ARR"}, + {"name": "The Navel (Extreme)", "level": 50, "expansion": "ARR"}, + {"name": "The Bowl of Embers (Extreme)", "level": 50, "expansion": "ARR"}, + {"name": "Thornmarch (Extreme)", "level": 50, "expansion": "ARR"}, + {"name": "The Whorleater (Extreme)", "level": 50, "expansion": "ARR"}, + {"name": "The Striking Tree (Extreme)", "level": 50, "expansion": "ARR"}, + {"name": "The Akh Afah Amphitheatre (Extreme)", "level": 50, "expansion": "ARR"}, + {"name": "The Limitless Blue (Extreme)", "level": 60, "expansion": "HW"}, + {"name": "Thok ast Thok (Extreme)", "level": 60, "expansion": "HW"}, + {"name": "The Minstrel's Ballad: Thordan's Reign", "level": 60, "expansion": "HW"}, + {"name": "The Minstrel's Ballad: Nidhogg's Rage", "level": 60, "expansion": "HW"}, + {"name": "Containment Bay S1T7 (Extreme)", "level": 60, "expansion": "HW"}, + {"name": "Containment Bay P1T6 (Extreme)", "level": 60, "expansion": "HW"}, + {"name": "Containment Bay Z1T9 (Extreme)", "level": 60, "expansion": "HW"}, + {"name": "The Pool of Tribute (Extreme)", "level": 70, "expansion": "SB"}, + {"name": "Emanation (Extreme)", "level": 70, "expansion": "SB"}, + {"name": "The Minstrel's Ballad: Shinryu's Domain", "level": 70, "expansion": "SB"}, + {"name": "The Minstrel's Ballad: Tsukuyomi's Pain", "level": 70, "expansion": "SB"}, + {"name": "The Great Hunt (Extreme)", "level": 70, "expansion": "SB"}, + {"name": "The Jade Stoa (Extreme)", "level": 70, "expansion": "SB"}, + {"name": "Hells' Kier (Extreme)", "level": 70, "expansion": "SB"}, + {"name": "The Wreath of Snakes (Extreme)", "level": 70, "expansion": "SB"}, + {"name": "The Dancing Plague (Extreme)", "level": 80, "expansion": "ShB"}, + {"name": "The Crown of the Immaculate (Extreme)", "level": 80, "expansion": "ShB"}, + {"name": "The Minstrel's Ballad: Hades's Elegy", "level": 80, "expansion": "ShB"}, + {"name": "Cinder Drift (Extreme)", "level": 80, "expansion": "ShB"}, + {"name": "Memoria Misera (Extreme)", "level": 80, "expansion": "ShB"}, + {"name": "The Seat of Sacrifice (Extreme)", "level": 80, "expansion": "ShB"}, + {"name": "Castrum Marinum (Extreme)", "level": 80, "expansion": "ShB"}, + {"name": "The Cloud Deck (Extreme)", "level": 80, "expansion": "ShB"}, + {"name": "The Minstrel's Ballad: Zodiark's Fall", "level": 90, "expansion": "EW"}, + {"name": "The Minstrel's Ballad: Hydaelyn's Call", "level": 90, "expansion": "EW"}, + {"name": "The Minstrel's Ballad: Endsinger's Aria", "level": 90, "expansion": "EW"}, + {"name": "Containment Bay S1T7 (Unreal)", "level": 90, "expansion": "EW"}, + {"name": "Storm's Crown (Extreme)", "level": 90, "expansion": "EW"} +] \ No newline at end of file diff --git a/duties/guildhests.json b/duties/guildhests.json new file mode 100644 index 0000000..db473e8 --- /dev/null +++ b/duties/guildhests.json @@ -0,0 +1,16 @@ +[ + {"name": "Basic Training: Enemy Parties", "level": 10, "expansion": "ARR"}, + {"name": "Under the Armor", "level": 10, "expansion": "ARR"}, + {"name": "Basic Training: Enemy Strongholds", "level": 15, "expansion": "ARR"}, + {"name": "Hero on the Half Shell", "level": 15, "expansion": "ARR"}, + {"name": "Pulling Poison Posies", "level": 20, "expansion": "ARR"}, + {"name": "Stinging Back", "level": 20, "expansion": "ARR"}, + {"name": "All's Well that Ends in the Well", "level": 25, "expansion": "ARR"}, + {"name": "Flicking Sticks and Taking Names", "level": 25, "expansion": "ARR"}, + {"name": "More than a Feeler", "level": 30, "expansion": "ARR"}, + {"name": "Annoy the Void", "level": 30, "expansion": "ARR"}, + {"name": "Shadow and Claw", "level": 35, "expansion": "ARR"}, + {"name": "Long Live the Queen", "level": 35, "expansion": "ARR"}, + {"name": "Ward Up", "level": 40, "expansion": "ARR"}, + {"name": "Solemn Trinity", "level": 40, "expansion": "ARR"} +] \ No newline at end of file diff --git a/duties/nraids.json b/duties/nraids.json new file mode 100644 index 0000000..98cdd3d --- /dev/null +++ b/duties/nraids.json @@ -0,0 +1,59 @@ +[ + {"name": "The Binding Coil of Bahamut - Turn 1", "level": 50, "expansion": "ARR"}, + {"name": "The Binding Coil of Bahamut - Turn 2", "level": 50, "expansion": "ARR"}, + {"name": "The Binding Coil of Bahamut - Turn 3", "level": 50, "expansion": "ARR"}, + {"name": "The Binding Coil of Bahamut - Turn 4", "level": 50, "expansion": "ARR"}, + {"name": "The Binding Coil of Bahamut - Turn 5", "level": 50, "expansion": "ARR"}, + {"name": "The Second Coil of Bahamut - Turn 1", "level": 50, "expansion": "ARR"}, + {"name": "The Second Coil of Bahamut - Turn 2", "level": 50, "expansion": "ARR"}, + {"name": "The Second Coil of Bahamut - Turn 3", "level": 50, "expansion": "ARR"}, + {"name": "The Second Coil of Bahamut - Turn 4", "level": 50, "expansion": "ARR"}, + {"name": "The Final Coil of Bahamut - Turn 1", "level": 50, "expansion": "ARR"}, + {"name": "The Final Coil of Bahamut - Turn 2", "level": 50, "expansion": "ARR"}, + {"name": "The Final Coil of Bahamut - Turn 3", "level": 50, "expansion": "ARR"}, + {"name": "The Final Coil of Bahamut - Turn 4", "level": 50, "expansion": "ARR"}, + {"name": "Alexander - The Fist of the Father", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Cuff of the Father", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Arm of the Father", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Burden of the Father", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Fist of the Son", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Cuff of the Son", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Arm of the Son", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Burden of the Son", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Eyes of the Creator", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Breath of the Creator", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Heart of the Creator", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Soul of the Creator", "level": 60, "expansion": "HW"}, + {"name": "Deltascape V1.0", "level": 70, "expansion": "SB"}, + {"name": "Deltascape V2.0", "level": 70, "expansion": "SB"}, + {"name": "Deltascape V3.0", "level": 70, "expansion": "SB"}, + {"name": "Deltascape V4.0", "level": 70, "expansion": "SB"}, + {"name": "Sigmascape V1.0", "level": 70, "expansion": "SB"}, + {"name": "Sigmascape V2.0", "level": 70, "expansion": "SB"}, + {"name": "Sigmascape V3.0", "level": 70, "expansion": "SB"}, + {"name": "Sigmascape V4.0", "level": 70, "expansion": "SB"}, + {"name": "Alphascape V1.0", "level": 70, "expansion": "SB"}, + {"name": "Alphascape V2.0", "level": 70, "expansion": "SB"}, + {"name": "Alphascape V3.0", "level": 70, "expansion": "SB"}, + {"name": "Alphascape V4.0", "level": 70, "expansion": "SB"}, + {"name": "Eden's Gate: Resurrection", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Gate: Descent", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Gate: Inundation", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Gate: Sepulture", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Verse: Fulmination", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Verse: Furor", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Verse: Iconoclasm", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Verse: Refulgence", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Promise: Umbra", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Promise: Litany", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Promise: Anamorphosis", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Promise: Eternity", "level": 80, "expansion": "ShB"}, + {"name": "Asphodelos: The First Circle", "level": 90, "expansion": "EW"}, + {"name": "Asphodelos: The Second Circle", "level": 90, "expansion": "EW"}, + {"name": "Asphodelos: The Third Circle", "level": 90, "expansion": "EW"}, + {"name": "Asphodelos: The Fourth Circle", "level": 90, "expansion": "EW"}, + {"name": "Abyssos: The Fifth Circle", "level": 90, "expansion": "EW"}, + {"name": "Abyssos: The Sixth Circle", "level": 90, "expansion": "EW"}, + {"name": "Abyssos: The Seventh Circle", "level": 90, "expansion": "EW"}, + {"name": "Abyssos: The Eighth Circle", "level": 90, "expansion": "EW"} +] \ No newline at end of file diff --git a/duties/pvp.json b/duties/pvp.json new file mode 100644 index 0000000..d104a7f --- /dev/null +++ b/duties/pvp.json @@ -0,0 +1,13 @@ +[ + {"name": "Crystalline Conflict (Casual Match)", "level": 30, "expansion": "ARR"}, + {"name": "Crystalline Conflict (Ranked Match)", "level": 30, "expansion": "ARR"}, + {"name": "Crystalline Conflict (Custom Match - The Palaistra)", "level": 30, "expansion": "ARR"}, + {"name": "Crystalline Conflict (Custom Match - The Volcanic Heart)", "level": 30, "expansion": "ARR"}, + {"name": "Crystalline Conflict (Custom Match - Cloud Nine)", "level": 30, "expansion": "ARR"}, + {"name": "The Borderland Ruins (Secure)", "level": 30, "expansion": "ARR"}, + {"name": "Seal Rock (Seize)", "level": 30, "expansion": "ARR"}, + {"name": "The Fields of Glory (Shatter)", "level": 30, "expansion": "ARR"}, + {"name": "Onsal Hakair (Danshig Naadam)", "level": 30, "expansion": "ARR"}, + {"name": "Astragalos", "level": 30, "expansion": "ARR"}, + {"name": "Hidden Gorge", "level": 30, "expansion": "ARR"} +] \ No newline at end of file diff --git a/duties/roulettes.json b/duties/roulettes.json new file mode 100644 index 0000000..5572804 --- /dev/null +++ b/duties/roulettes.json @@ -0,0 +1,13 @@ +[ + {"name": "Expert", "level": 90}, + {"name": "Level 90 Dungeons", "level": 90}, + {"name": "Level 50/60/70/80", "level": 50}, + {"name": "Leveling", "level": 16}, + {"name": "Trials", "level": 50}, + {"name": "Main Scenario", "level": 50}, + {"name": "Guildhests", "level": 10}, + {"name": "Alliance Raid", "level": 50}, + {"name": "Normal Raid", "level": 60}, + {"name": "Mentor", "level": 90}, + {"name": "Frontline", "level": 30} +] \ No newline at end of file diff --git a/duties/savage.json b/duties/savage.json new file mode 100644 index 0000000..cd19e54 --- /dev/null +++ b/duties/savage.json @@ -0,0 +1,50 @@ +[ + {"name": "The Second Coil of Bahamut (Savage) - Turn 1", "level": 50, "expansion": "ARR"}, + {"name": "The Second Coil of Bahamut (Savage) - Turn 2", "level": 50, "expansion": "ARR"}, + {"name": "The Second Coil of Bahamut (Savage) - Turn 3", "level": 50, "expansion": "ARR"}, + {"name": "The Second Coil of Bahamut (Savage) - Turn 4", "level": 50, "expansion": "ARR"}, + {"name": "Alexander - The Fist of the Father (Savage)", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Cuff of the Father (Savage)", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Arm of the Father (Savage)", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Burden of the Father (Savage)", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Fist of the Son (Savage)", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Cuff of the Son (Savage)", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Arm of the Son (Savage)", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Burden of the Son (Savage)", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Eyes of the Creator (Savage)", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Breath of the Creator (Savage)", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Heart of the Creator (Savage)", "level": 60, "expansion": "HW"}, + {"name": "Alexander - The Soul of the Creator (Savage)", "level": 60, "expansion": "HW"}, + {"name": "Deltascape V1.0 (Savage)", "level": 70, "expansion": "SB"}, + {"name": "Deltascape V2.0 (Savage)", "level": 70, "expansion": "SB"}, + {"name": "Deltascape V3.0 (Savage)", "level": 70, "expansion": "SB"}, + {"name": "Deltascape V4.0 (Savage)", "level": 70, "expansion": "SB"}, + {"name": "Sigmascape V1.0 (Savage)", "level": 70, "expansion": "SB"}, + {"name": "Sigmascape V2.0 (Savage)", "level": 70, "expansion": "SB"}, + {"name": "Sigmascape V3.0 (Savage)", "level": 70, "expansion": "SB"}, + {"name": "Sigmascape V4.0 (Savage)", "level": 70, "expansion": "SB"}, + {"name": "Alphascape V1.0 (Savage)", "level": 70, "expansion": "SB"}, + {"name": "Alphascape V2.0 (Savage)", "level": 70, "expansion": "SB"}, + {"name": "Alphascape V3.0 (Savage)", "level": 70, "expansion": "SB"}, + {"name": "Alphascape V4.0 (Savage)", "level": 70, "expansion": "SB"}, + {"name": "Eden's Gate: Resurrection (Savage)", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Gate: Descent (Savage)", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Gate: Inundation (Savage)", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Gate: Sepulture (Savage)", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Verse: Fulmination (Savage)", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Verse: Furor (Savage)", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Verse: Iconoclasm (Savage)", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Verse: Refulgence (Savage)", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Promise: Umbra (Savage)", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Promise: Litany (Savage)", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Promise: Anamorphosis (Savage)", "level": 80, "expansion": "ShB"}, + {"name": "Eden's Promise: Eternity (Savage)", "level": 80, "expansion": "ShB"}, + {"name": "Asphodelos: The First Circle (Savage)", "level": 90, "expansion": "EW"}, + {"name": "Asphodelos: The Second Circle (Savage)", "level": 90, "expansion": "EW"}, + {"name": "Asphodelos: The Third Circle (Savage)", "level": 90, "expansion": "EW"}, + {"name": "Asphodelos: The Fourth Circle (Savage)", "level": 90, "expansion": "EW"}, + {"name": "Abyssos: The Fifth Circle (Savage)", "level": 90, "expansion": "EW"}, + {"name": "Abyssos: The Sixth Circle (Savage)", "level": 90, "expansion": "EW"}, + {"name": "Abyssos: The Seventh Circle (Savage)", "level": 90, "expansion": "EW"}, + {"name": "Abyssos: The Eighth Circle (Savage)", "level": 90, "expansion": "EW"} +] \ No newline at end of file diff --git a/duties/trials.json b/duties/trials.json new file mode 100644 index 0000000..8c7964b --- /dev/null +++ b/duties/trials.json @@ -0,0 +1,48 @@ +[ + {"name": "The Bowl of Embers", "level": 20, "expansion": "ARR"}, + {"name": "The Navel", "level": 34, "expansion": "ARR"}, + {"name": "The Howling Eye", "level": 44, "expansion": "ARR"}, + {"name": "The Porta Decumana", "level": 50, "expansion": "ARR"}, + {"name": "The Chrysalis", "level": 50, "expansion": "ARR"}, + {"name": "A Relic Reborn: the Chimera", "level": 50, "expansion": "ARR"}, + {"name": "A Relic Reborn: the Hydra", "level": 50, "expansion": "ARR"}, + {"name": "Battle on the Big Bridge", "level": 50, "expansion": "ARR"}, + {"name": "The Dragon's Neck", "level": 50, "expansion": "ARR"}, + {"name": "Battle in the Big Keep", "level": 50, "expansion": "ARR"}, + {"name": "The Bowl of Embers (Hard)", "level": 50, "expansion": "ARR"}, + {"name": "The Howling Eye (Hard)", "level": 50, "expansion": "ARR"}, + {"name": "The Navel (Hard)", "level": 50, "expansion": "ARR"}, + {"name": "Thornmarch (Hard)", "level": 50, "expansion": "ARR"}, + {"name": "The Whorleater (Hard)", "level": 50, "expansion": "ARR"}, + {"name": "The Striking Tree (Hard)", "level": 50, "expansion": "ARR"}, + {"name": "The Akh Afah Amphitheatre (Hard)", "level": 50, "expansion": "ARR"}, + {"name": "Urth's Fount", "level": 50, "expansion": "ARR"}, + {"name": "The Minstrel's Ballad: Ultima's Bane", "level": 50, "expansion": "ARR"}, + {"name": "Thok ast Thok (Hard)", "level": 53, "expansion": "HW"}, + {"name": "The Limitless Blue (Hard)", "level": 57, "expansion": "HW"}, + {"name": "The Singularity Reactor", "level": 60, "expansion": "HW"}, + {"name": "The Final Steps of Faith", "level": 60, "expansion": "HW"}, + {"name": "Containment Bay S1T7", "level": 60, "expansion": "HW"}, + {"name": "Containment Bay P1T6", "level": 60, "expansion": "HW"}, + {"name": "Containment Bay Z1T9", "level": 60, "expansion": "HW"}, + {"name": "The Pool of Tribute", "level": 63, "expansion": "SB"}, + {"name": "Emanation", "level": 67, "expansion": "SB"}, + {"name": "The Royal Menagerie", "level": 70, "expansion": "SB"}, + {"name": "Castrum Fluminis", "level": 70, "expansion": "SB"}, + {"name": "Kugane Ohashi", "level": 70, "expansion": "SB"}, + {"name": "The Great Hunt", "level": 70, "expansion": "SB"}, + {"name": "The Jade Stoa", "level": 70, "expansion": "SB"}, + {"name": "Hells' Kier", "level": 70, "expansion": "SB"}, + {"name": "The Wreath of Snakes", "level": 70, "expansion": "SB"}, + {"name": "The Dancing Plague", "level": 73, "expansion": "ShB"}, + {"name": "The Crown of the Immaculate", "level": 79, "expansion": "ShB"}, + {"name": "The Dying Gasp", "level": 80, "expansion": "ShB"}, + {"name": "Cinder Drift", "level": 80, "expansion": "ShB"}, + {"name": "The Seat of Sacrifice", "level": 80, "expansion": "ShB"}, + {"name": "Castrum Marinum", "level": 80, "expansion": "ShB"}, + {"name": "The Cloud Deck", "level": 80, "expansion": "ShB"}, + {"name": "The Dark Inside", "level": 83, "expansion": "EW"}, + {"name": "The Mothercrystal", "level": 89, "expansion": "EW"}, + {"name": "The Final Day", "level": 90, "expansion": "EW"}, + {"name": "Storm's Crown", "level": 90, "expansion": "EW"} +] \ No newline at end of file diff --git a/duties/ultimates.json b/duties/ultimates.json new file mode 100644 index 0000000..82c1ff7 --- /dev/null +++ b/duties/ultimates.json @@ -0,0 +1,6 @@ +[ + {"name": "The Unending Coil of Bahamut (Ultimate)", "level": 70, "expansion": "SB"}, + {"name": "The Weapon's Refrain (Ultimate)", "level": 70, "expansion": "SB"}, + {"name": "The Epic of Alexander (Ultimate)", "level": 80, "expansion": "ShB"}, + {"name": "Dragonsong's Reprise (Ultimate)", "level": 90, "expansion": "EW"} +] \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..062a386 --- /dev/null +++ b/index.js @@ -0,0 +1,71 @@ +const DiscordJS = require('discord.js') +const WOKCommands = require('wokcommands') +const path = require('path') +require('dotenv').config(); + +const { Intents } = DiscordJS +const client = new DiscordJS.Client({ + intents: [ + Intents.FLAGS.GUILDS, + Intents.FLAGS.GUILD_MESSAGES, + Intents.FLAGS.GUILD_MESSAGE_REACTIONS, + ], +}) +/* + To-Do: + - animal spawn time with weather condition check + - lodestone lookup???? + - change database structure: duties in one, filter by type (e.g. Dungeon, Raid. etc); classes in one, filter by type (e.g. Tank, Healer, etc) +*/ + +client.on('ready', async () => { + const dbOptions = { + keepAlive: true + } + new WOKCommands(client, { + commandsDir: path.join(__dirname, 'commands'), + featuresDir: path.join(__dirname, 'features'), + messagesPath: '', + typeScript: false, + showWarns: true, + delErrMsgCooldown: -1, + defaultLangauge: 'english', + ignoreBots: false, + ephemeral: false, + dbOptions: { + // These are the default options + keepAlive: true + }, + testServers: ['848610258306072576'], + botOwners: ['140508899064283136'], + disabledDefaultCommands: [ + // 'help', + // 'command', + // 'language', + // 'prefix', + // 'requiredrole', + // 'channelonly' + ], + mongoUri: process.env.URI, + debug: false +}) + .setDefaultPrefix('$') + // Used for the color of embeds sent by WOKCommands + .setColor(0xff0000) +}) + +client.login(process.env.TOKEN) + +/* +SUB_COMMAND 1 +SUB_COMMAND_GROUP 2 +STRING 3 +INTEGER 4 Any integer between -2^53 and 2^53 +BOOLEAN 5 +USER 6 +CHANNEL 7 Includes all channel types + categories +ROLE 8 +MENTIONABLE 9 Includes users and roles +NUMBER 10 Any double between -2^53 and 2^53 +ATTACHMENT 11 attachment object +*/ \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..b5de689 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,987 @@ +{ + "name": "shaitest", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "shaitest", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "dotenv": "^16.0.2", + "mongodb": "^4.9.1", + "mongoose": "^6.6.0", + "wokcommands": "^1.5.3" + } + }, + "node_modules/@discordjs/builders": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.16.0.tgz", + "integrity": "sha512-9/NCiZrLivgRub2/kBc0Vm5pMBE5AUdYbdXsLu/yg9ANgvnaJ0bZKTY8yYnLbsEc/LYUP79lEIdC73qEYhWq7A==", + "deprecated": "no longer supported", + "dependencies": { + "@sapphire/shapeshift": "^3.5.1", + "discord-api-types": "^0.36.2", + "fast-deep-equal": "^3.1.3", + "ts-mixer": "^6.0.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/@discordjs/builders/node_modules/discord-api-types": { + "version": "0.36.3", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.36.3.tgz", + "integrity": "sha512-bz/NDyG0KBo/tY14vSkrwQ/n3HKPf87a0WFW/1M9+tXYK+vp5Z5EksawfCWo2zkAc6o7CClc0eff1Pjrqznlwg==" + }, + "node_modules/@discordjs/collection": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.7.0.tgz", + "integrity": "sha512-R5i8Wb8kIcBAFEPLLf7LVBQKBDYUL+ekb23sOgpkpyGT+V4P7V83wTxcsqmX+PbqHt4cEHn053uMWfRqh/Z/nA==", + "deprecated": "no longer supported", + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/@sapphire/async-queue": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.0.tgz", + "integrity": "sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@sapphire/shapeshift": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.6.0.tgz", + "integrity": "sha512-tu2WLRdo5wotHRvsCkspg3qMiP6ETC3Q1dns1Q5V6zKUki+1itq6AbhMwohF9ZcLoYqg+Y8LkgRRtVxxTQVTBQ==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "lodash.uniqwith": "^4.5.0" + }, + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@types/node": { + "version": "18.7.16", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.16.tgz", + "integrity": "sha512-EQHhixfu+mkqHMZl1R2Ovuvn47PUw18azMJOTwSZr9/fhzHNGXAJ0ma0dayRVchprpCj0Kc1K1xKoWaATWF1qg==" + }, + "node_modules/@types/node-fetch": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz", + "integrity": "sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==", + "dependencies": { + "@types/node": "*", + "form-data": "^3.0.0" + } + }, + "node_modules/@types/node-fetch/node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==" + }, + "node_modules/@types/whatwg-url": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", + "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", + "dependencies": { + "@types/node": "*", + "@types/webidl-conversions": "*" + } + }, + "node_modules/@types/ws": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", + "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bson": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-4.7.0.tgz", + "integrity": "sha512-VrlEE4vuiO1WTpfof4VmaVolCVYkYTgB9iWgYNOrVlnifpME/06fhFRmONgBhClD5pFC1t9ZWqFUQEQAzY43bA==", + "dependencies": { + "buffer": "^5.6.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debug/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==" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/discord-api-types": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.5.tgz", + "integrity": "sha512-dvO5M52v7m7Dy96+XUnzXNsQ/0npsYpU6dL205kAtEDueswoz3aU3bh1UMoK4cQmcGtB1YRyLKqp+DXi05lzFg==" + }, + "node_modules/discord.js": { + "version": "13.10.3", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.10.3.tgz", + "integrity": "sha512-cIARuxfpQDeqA9Zw3fz4IL20xAhtMsjwJIf7/K82R3n2xROG9/fAx+7qjX8ysp9BfflYqMu2ZskyWq1EAmL5BA==", + "dependencies": { + "@discordjs/builders": "^0.16.0", + "@discordjs/collection": "^0.7.0", + "@sapphire/async-queue": "^1.5.0", + "@types/node-fetch": "^2.6.2", + "@types/ws": "^8.5.3", + "discord-api-types": "^0.33.3", + "form-data": "^4.0.0", + "node-fetch": "^2.6.7", + "ws": "^8.8.1" + }, + "engines": { + "node": ">=16.6.0", + "npm": ">=7.0.0" + } + }, + "node_modules/dotenv": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.2.tgz", + "integrity": "sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" + }, + "node_modules/kareem": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.4.1.tgz", + "integrity": "sha512-aJ9opVoXroQUPfovYP5kaj2lM7Jn02Gw13bL0lg9v0V7SaUc0qavPs0Eue7d2DcC3NjqI6QAUElXNsuZSeM+EA==" + }, + "node_modules/lodash.uniqwith": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniqwith/-/lodash.uniqwith-4.5.0.tgz", + "integrity": "sha512-7lYL8bLopMoy4CTICbxygAUq6CdRJ36vFc80DucPueUee+d5NBRxz3FdT9Pes/HEx5mPoT9jwnsEJWz1N7uq7Q==" + }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mongodb": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.9.1.tgz", + "integrity": "sha512-ZhgI/qBf84fD7sI4waZBoLBNJYPQN5IOC++SBCiPiyhzpNKOxN/fi0tBHvH2dEC42HXtNEbFB0zmNz4+oVtorQ==", + "dependencies": { + "bson": "^4.7.0", + "denque": "^2.1.0", + "mongodb-connection-string-url": "^2.5.3", + "socks": "^2.7.0" + }, + "engines": { + "node": ">=12.9.0" + }, + "optionalDependencies": { + "saslprep": "^1.0.3" + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.5.3.tgz", + "integrity": "sha512-f+/WsED+xF4B74l3k9V/XkTVj5/fxFH2o5ToKXd8Iyi5UhM+sO9u0Ape17Mvl/GkZaFtM0HQnzAG5OTmhKw+tQ==", + "dependencies": { + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^11.0.0" + } + }, + "node_modules/mongoose": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-6.6.0.tgz", + "integrity": "sha512-5sS0D7qbmfT4G/nODkJhx5l2qvhqLMplhMlp08Wea8eoi6O/B6b+o1ukUEKjjm1MV8dAS3w8kx47R/klYKLPpQ==", + "dependencies": { + "bson": "^4.6.5", + "kareem": "2.4.1", + "mongodb": "4.9.1", + "mpath": "0.9.0", + "mquery": "4.0.3", + "ms": "2.1.3", + "sift": "16.0.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-4.0.3.tgz", + "integrity": "sha512-J5heI+P08I6VJ2Ky3+33IpCdAvlYGTSUjwTPxkAr8i8EoduPMBX2OY/wa3IKZIQl7MU4SbFk8ndgSKyB/cl1zA==", + "dependencies": { + "debug": "4.x" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "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==" + }, + "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==" + }, + "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==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/saslprep": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", + "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "optional": true, + "dependencies": { + "sparse-bitfield": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sift": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.0.tgz", + "integrity": "sha512-ILTjdP2Mv9V1kIxWMXeMTIRbOBrqKc4JAXmFMnFq3fKeyQ2Qwa3Dw1ubcye3vR+Y6ofA0b9gNDr/y2t6eUeIzQ==" + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.0.tgz", + "integrity": "sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA==", + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "optional": true, + "dependencies": { + "memory-pager": "^1.0.2" + } + }, + "node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/ts-mixer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.1.tgz", + "integrity": "sha512-hvE+ZYXuINrx6Ei6D6hz+PTim0Uf++dYbK9FFifLNwQj+RwKquhQpn868yZsCtJYiclZF1u8l6WZxxKi+vv7Rg==" + }, + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/wokcommands": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/wokcommands/-/wokcommands-1.5.3.tgz", + "integrity": "sha512-oBb7ujov8zJ1DYSLz3G7OW9DJK+0l35t/ds5j/2nJ+4DwfzLU7w4i2yXGZOidSHkkygSegiNuaWKfZTP2okJOw==", + "dependencies": { + "discord.js": "^13.1.0", + "dotenv": "^8.2.0", + "mongoose": "^6.0.10" + } + }, + "node_modules/wokcommands/node_modules/dotenv": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", + "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", + "engines": { + "node": ">=10" + } + }, + "node_modules/ws": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", + "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + } + }, + "dependencies": { + "@discordjs/builders": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.16.0.tgz", + "integrity": "sha512-9/NCiZrLivgRub2/kBc0Vm5pMBE5AUdYbdXsLu/yg9ANgvnaJ0bZKTY8yYnLbsEc/LYUP79lEIdC73qEYhWq7A==", + "requires": { + "@sapphire/shapeshift": "^3.5.1", + "discord-api-types": "^0.36.2", + "fast-deep-equal": "^3.1.3", + "ts-mixer": "^6.0.1", + "tslib": "^2.4.0" + }, + "dependencies": { + "discord-api-types": { + "version": "0.36.3", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.36.3.tgz", + "integrity": "sha512-bz/NDyG0KBo/tY14vSkrwQ/n3HKPf87a0WFW/1M9+tXYK+vp5Z5EksawfCWo2zkAc6o7CClc0eff1Pjrqznlwg==" + } + } + }, + "@discordjs/collection": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.7.0.tgz", + "integrity": "sha512-R5i8Wb8kIcBAFEPLLf7LVBQKBDYUL+ekb23sOgpkpyGT+V4P7V83wTxcsqmX+PbqHt4cEHn053uMWfRqh/Z/nA==" + }, + "@sapphire/async-queue": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.0.tgz", + "integrity": "sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==" + }, + "@sapphire/shapeshift": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.6.0.tgz", + "integrity": "sha512-tu2WLRdo5wotHRvsCkspg3qMiP6ETC3Q1dns1Q5V6zKUki+1itq6AbhMwohF9ZcLoYqg+Y8LkgRRtVxxTQVTBQ==", + "requires": { + "fast-deep-equal": "^3.1.3", + "lodash.uniqwith": "^4.5.0" + } + }, + "@types/node": { + "version": "18.7.16", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.16.tgz", + "integrity": "sha512-EQHhixfu+mkqHMZl1R2Ovuvn47PUw18azMJOTwSZr9/fhzHNGXAJ0ma0dayRVchprpCj0Kc1K1xKoWaATWF1qg==" + }, + "@types/node-fetch": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz", + "integrity": "sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==", + "requires": { + "@types/node": "*", + "form-data": "^3.0.0" + }, + "dependencies": { + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } + }, + "@types/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==" + }, + "@types/whatwg-url": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", + "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", + "requires": { + "@types/node": "*", + "@types/webidl-conversions": "*" + } + }, + "@types/ws": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", + "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", + "requires": { + "@types/node": "*" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bson": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-4.7.0.tgz", + "integrity": "sha512-VrlEE4vuiO1WTpfof4VmaVolCVYkYTgB9iWgYNOrVlnifpME/06fhFRmONgBhClD5pFC1t9ZWqFUQEQAzY43bA==", + "requires": { + "buffer": "^5.6.0" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "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" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==" + }, + "discord-api-types": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.5.tgz", + "integrity": "sha512-dvO5M52v7m7Dy96+XUnzXNsQ/0npsYpU6dL205kAtEDueswoz3aU3bh1UMoK4cQmcGtB1YRyLKqp+DXi05lzFg==" + }, + "discord.js": { + "version": "13.10.3", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.10.3.tgz", + "integrity": "sha512-cIARuxfpQDeqA9Zw3fz4IL20xAhtMsjwJIf7/K82R3n2xROG9/fAx+7qjX8ysp9BfflYqMu2ZskyWq1EAmL5BA==", + "requires": { + "@discordjs/builders": "^0.16.0", + "@discordjs/collection": "^0.7.0", + "@sapphire/async-queue": "^1.5.0", + "@types/node-fetch": "^2.6.2", + "@types/ws": "^8.5.3", + "discord-api-types": "^0.33.3", + "form-data": "^4.0.0", + "node-fetch": "^2.6.7", + "ws": "^8.8.1" + } + }, + "dotenv": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.2.tgz", + "integrity": "sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA==" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" + }, + "kareem": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.4.1.tgz", + "integrity": "sha512-aJ9opVoXroQUPfovYP5kaj2lM7Jn02Gw13bL0lg9v0V7SaUc0qavPs0Eue7d2DcC3NjqI6QAUElXNsuZSeM+EA==" + }, + "lodash.uniqwith": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniqwith/-/lodash.uniqwith-4.5.0.tgz", + "integrity": "sha512-7lYL8bLopMoy4CTICbxygAUq6CdRJ36vFc80DucPueUee+d5NBRxz3FdT9Pes/HEx5mPoT9jwnsEJWz1N7uq7Q==" + }, + "memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "mongodb": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.9.1.tgz", + "integrity": "sha512-ZhgI/qBf84fD7sI4waZBoLBNJYPQN5IOC++SBCiPiyhzpNKOxN/fi0tBHvH2dEC42HXtNEbFB0zmNz4+oVtorQ==", + "requires": { + "bson": "^4.7.0", + "denque": "^2.1.0", + "mongodb-connection-string-url": "^2.5.3", + "saslprep": "^1.0.3", + "socks": "^2.7.0" + } + }, + "mongodb-connection-string-url": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.5.3.tgz", + "integrity": "sha512-f+/WsED+xF4B74l3k9V/XkTVj5/fxFH2o5ToKXd8Iyi5UhM+sO9u0Ape17Mvl/GkZaFtM0HQnzAG5OTmhKw+tQ==", + "requires": { + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^11.0.0" + } + }, + "mongoose": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-6.6.0.tgz", + "integrity": "sha512-5sS0D7qbmfT4G/nODkJhx5l2qvhqLMplhMlp08Wea8eoi6O/B6b+o1ukUEKjjm1MV8dAS3w8kx47R/klYKLPpQ==", + "requires": { + "bson": "^4.6.5", + "kareem": "2.4.1", + "mongodb": "4.9.1", + "mpath": "0.9.0", + "mquery": "4.0.3", + "ms": "2.1.3", + "sift": "16.0.0" + } + }, + "mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==" + }, + "mquery": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-4.0.3.tgz", + "integrity": "sha512-J5heI+P08I6VJ2Ky3+33IpCdAvlYGTSUjwTPxkAr8i8EoduPMBX2OY/wa3IKZIQl7MU4SbFk8ndgSKyB/cl1zA==", + "requires": { + "debug": "4.x" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + }, + "dependencies": { + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "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==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "saslprep": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", + "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "optional": true, + "requires": { + "sparse-bitfield": "^3.0.3" + } + }, + "sift": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.0.tgz", + "integrity": "sha512-ILTjdP2Mv9V1kIxWMXeMTIRbOBrqKc4JAXmFMnFq3fKeyQ2Qwa3Dw1ubcye3vR+Y6ofA0b9gNDr/y2t6eUeIzQ==" + }, + "smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" + }, + "socks": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.0.tgz", + "integrity": "sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA==", + "requires": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + } + }, + "sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "optional": true, + "requires": { + "memory-pager": "^1.0.2" + } + }, + "tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "requires": { + "punycode": "^2.1.1" + } + }, + "ts-mixer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.1.tgz", + "integrity": "sha512-hvE+ZYXuINrx6Ei6D6hz+PTim0Uf++dYbK9FFifLNwQj+RwKquhQpn868yZsCtJYiclZF1u8l6WZxxKi+vv7Rg==" + }, + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" + }, + "whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "requires": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + } + }, + "wokcommands": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/wokcommands/-/wokcommands-1.5.3.tgz", + "integrity": "sha512-oBb7ujov8zJ1DYSLz3G7OW9DJK+0l35t/ds5j/2nJ+4DwfzLU7w4i2yXGZOidSHkkygSegiNuaWKfZTP2okJOw==", + "requires": { + "discord.js": "^13.1.0", + "dotenv": "^8.2.0", + "mongoose": "^6.0.10" + }, + "dependencies": { + "dotenv": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", + "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==" + } + } + }, + "ws": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", + "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", + "requires": {} + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..e9dd9f4 --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "shaitest", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "dotenv": "^16.0.2", + "mongodb": "^4.9.1", + "mongoose": "^6.6.0", + "wokcommands": "^1.5.3" + } +} diff --git a/schemas/classSchema.js b/schemas/classSchema.js new file mode 100644 index 0000000..2f0ed2d --- /dev/null +++ b/schemas/classSchema.js @@ -0,0 +1,18 @@ +const { default: mongoose } = require("mongoose"); + +const reqString = { + type: String, + required: true, +} + +const reqInteger = { + type: Number, + required: true, +} + +const classSchema = new mongoose.Schema({ + _id: reqInteger, + job: reqString +}) + +module.exports = mongoose.model('classes', classSchema) \ No newline at end of file diff --git a/schemas/cookieSchema.js b/schemas/cookieSchema.js new file mode 100644 index 0000000..ed1f0cf --- /dev/null +++ b/schemas/cookieSchema.js @@ -0,0 +1,19 @@ +const mongoose = require('mongoose') + +const reqString = { + type: String, + required: true, +} +const reqInteger = { + type: Number, + required: true, +} + +const cookieSchema = new mongoose.Schema({ + //Guild ID + _id: reqString, + user: reqString, + cookies: reqInteger +}) + +module.exports = mongoose.model('Cookies', cookieSchema) \ No newline at end of file diff --git a/schemas/cooldownSchema.js b/schemas/cooldownSchema.js new file mode 100644 index 0000000..b870e5d --- /dev/null +++ b/schemas/cooldownSchema.js @@ -0,0 +1,20 @@ +const { default: mongoose } = require("mongoose"); + +const reqString = { + type: String, + required: true, +} + +const reqInteger = { + type: Number, + required: true, +} + +const cooldownSchema = new mongoose.Schema({ + _id: reqString, + command: reqString, + subcommand: reqString, + cooldown: reqInteger +}) + +module.exports = mongoose.model('cooldowns', cooldownSchema) \ No newline at end of file