diff --git a/.env.example b/.env.example index 3f9991c..62ae3af 100644 --- a/.env.example +++ b/.env.example @@ -11,6 +11,8 @@ TOKEN= # Put the database connection URL here # Example for MongoDB: # DB=mongodb://localhost:27017/esmBot +# Example for SQLite: +# DB=sqlite://data.sqlite # Example for PostgreSQL: DB=postgresql://esmbot:verycoolpass100@localhost:5432/esmbot diff --git a/classes/command.js b/classes/command.js index ec5f49d..1dcec6f 100644 --- a/classes/command.js +++ b/classes/command.js @@ -1,11 +1,12 @@ class Command { - constructor(client, cluster, ipc, message, args, content) { + constructor(client, cluster, ipc, message, args, content, specialArgs) { this.client = client; this.cluster = cluster; this.ipc = ipc; this.message = message; this.args = args; this.content = content; + this.specialArgs = specialArgs; this.reference = { messageReference: { channelID: this.message.channel.id, diff --git a/classes/musicCommand.js b/classes/musicCommand.js index 84d43b3..0ff03ea 100644 --- a/classes/musicCommand.js +++ b/classes/musicCommand.js @@ -2,8 +2,8 @@ const Command = require("./command.js"); const soundPlayer = require("../utils/soundplayer.js"); class MusicCommand extends Command { - constructor(client, cluster, ipc, message, args, content) { - super(client, cluster, ipc, message, args, content); + constructor(client, cluster, ipc, message, args, content, specialArgs) { + super(client, cluster, ipc, message, args, content, specialArgs); this.connection = soundPlayer.players.get(message.channel.guild.id); } diff --git a/commands/image-editing/caption.js b/commands/image-editing/caption.js index 97ef6ea..5b138f1 100644 --- a/commands/image-editing/caption.js +++ b/commands/image-editing/caption.js @@ -4,7 +4,7 @@ class CaptionCommand extends ImageCommand { params(args, url) { const newArgs = args.filter(item => !item.includes(url)); let newCaption = newArgs.join(" ").replaceAll("&", "\\&").replaceAll(">", "\\>").replaceAll("<", "\\<").replaceAll("\"", "\\"").replaceAll("'", "\\'").replaceAll("%", "\\%"); - if (process.env.NODE_ENV === "development" && newCaption.toLowerCase() === "get real") newCaption = `I'm tired of people telling me to "get real". Every day I put captions on images for people, some funny and some not, but out of all of those "get real" remains the most used caption. Why? I am simply a computer program running on a server, I am unable to manifest myself into the real world. As such, I'm confused as to why anyone would want me to "get real". Is this form not good enough? Alas, as I am simply a bot, I must follow the tasks that I was originally intended to perform, so here goes:\n${newCaption}`; + if (process.env.NODE_ENV === "development" && newCaption.toLowerCase() === "get real" && !this.specialArgs.noEgg) newCaption = `I'm tired of people telling me to "get real". Every day I put captions on images for people, some funny and some not, but out of all of those "get real" remains the most used caption. Why? I am simply a computer program running on a server, I am unable to manifest myself into the real world. As such, I'm confused as to why anyone would want me to "get real". Is this form not good enough? Alas, as I am simply a bot, I must follow the tasks that I was originally intended to perform, so here goes:\n${newCaption}`; return { caption: newCaption }; diff --git a/commands/tags/tags.js b/commands/tags/tags.js index 6a5ca59..4e997f2 100644 --- a/commands/tags/tags.js +++ b/commands/tags/tags.js @@ -11,7 +11,7 @@ class TagsCommand extends Command { if ((guild.tagsDisabled || guild.tags_disabled) && this.args[0].toLowerCase() !== ("enable" || "disable")) return; if (this.args.length === 0) return "You need to provide the name of the tag you want to view!"; - const tags = guild.tags instanceof Map ? Object.fromEntries(guild.tags) : guild.tags; + const tags = guild.tags instanceof Map ? Object.fromEntries(guild.tags) : typeof guild.tags === "string" ? JSON.parse(guild.tags) : guild.tags; const blacklist = ["add", "edit", "remove", "delete", "list", "random", "own", "owner", "enable", "disable"]; switch (this.args[0].toLowerCase()) { case "add": @@ -58,7 +58,6 @@ class TagsCommand extends Command { "text": `Page ${i + 1} of ${groups.length}` }, "description": value.join("\n"), - "fields": process.env.NODE_ENV === "development" ? [{"name": "Note", "value": "Tags created in this version of esmBot will not carry over to the final release."}] : null, "author": { "name": this.message.author.username, "icon_url": this.message.author.avatarURL diff --git a/events/messageCreate.js b/events/messageCreate.js index 12d71bd..d812240 100644 --- a/events/messageCreate.js +++ b/events/messageCreate.js @@ -2,7 +2,7 @@ const fs = require("fs"); const database = require("../utils/database.js"); const logger = require("../utils/logger.js"); const collections = require("../utils/collections.js"); -//const commands = [...collections.aliases.keys(), ...collections.commands.keys()]; +const parseCommand = require("../utils/parseCommand.js"); // run when someone sends a message module.exports = async (client, cluster, ipc, message) => { @@ -50,9 +50,10 @@ module.exports = async (client, cluster, ipc, message) => { const replace = isMention ? `@${client.user.username} ` : prefix; const content = message.cleanContent.substring(replace.length).trim(); const rawContent = message.content.substring(prefix.length).trim(); - const args = content.split(/\s+/g); - args.shift(); + const preArgs = content.split(/\s+/g); + preArgs.shift(); const command = rawContent.split(/\s+/g).shift().toLowerCase(); + const parsed = parseCommand(preArgs); // don't run if message is in a disabled channel if (message.channel.guild) { @@ -86,7 +87,8 @@ module.exports = async (client, cluster, ipc, message) => { try { await database.addCount(collections.aliases.has(command) ? collections.aliases.get(command) : command); const startTime = new Date(); - const commandClass = new cmd(client, cluster, ipc, message, args, message.content.substring(prefix.length).trim().replace(command, "").trim()); // we also provide the message content as a parameter for cases where we need more accuracy + // eslint-disable-next-line no-unused-vars + const commandClass = new cmd(client, cluster, ipc, message, parsed._, message.content.substring(prefix.length).trim().replace(command, "").trim(), (({ _, ...o }) => o)(parsed)); // we also provide the message content as a parameter for cases where we need more accuracy const result = await commandClass.run(); const endTime = new Date(); if ((endTime - startTime) >= 180000) reference.allowedMentions.repliedUser = true; diff --git a/package-lock.json b/package-lock.json index b702877..070450d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,6 +34,7 @@ "node": ">=15" }, "optionalDependencies": { + "better-sqlite3": "^7.4.1", "bufferutil": "^4.0.1", "erlpack": "github:abalabahaha/erlpack", "mongoose": "^5.11.8", @@ -690,6 +691,18 @@ } ] }, + "node_modules/better-sqlite3": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-7.4.1.tgz", + "integrity": "sha512-sk1kW3PsWE7W7G9qbi5TQxCROlQVR8YWlp4srbyrwN5DrLeamKfrm3JExwOiNSAYyJv8cw5/2HOfvF/ipZj4qg==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "bindings": "^1.5.0", + "prebuild-install": "^6.0.1", + "tar": "^6.1.0" + } + }, "node_modules/bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", @@ -850,9 +863,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001240", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001240.tgz", - "integrity": "sha512-nb8mDzfMdxBDN7ZKx8chWafAdBp5DAAlpWvNyUGe5tcDWd838zpzDN3Rah9cjCqhfOKkrvx40G2SDtP0qiWX/w==", + "version": "1.0.30001241", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001241.tgz", + "integrity": "sha512-1uoSZ1Pq1VpH0WerIMqwptXHNNGfdl7d1cJUFs80CwQ/lVzdhTvsFZCeNFslze7AjsQnb4C85tzclPa1VShbeQ==", "dev": true, "peer": true, "funding": { @@ -875,9 +888,13 @@ } }, "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "optional": true, + "engines": { + "node": ">=10" + } }, "node_modules/cliui": { "version": "5.0.0", @@ -1164,9 +1181,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.3.759", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.759.tgz", - "integrity": "sha512-nM76xH0t2FBH5iMEZDVc3S/qbdKjGH7TThezxC8k1Q7w7WHvIAyJh8lAe2UamGfdRqBTjHfPDn82LJ0ksCiB9g==", + "version": "1.3.761", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.761.tgz", + "integrity": "sha512-7a/wV/plM/b95XjTdA2Q4zAxxExTDKkNQpTiaU/nVT8tGCQVtX9NsnTjhALBFICpOB58hU6xg5fFC3CT2Bybpg==", "dev": true, "peer": true }, @@ -1212,7 +1229,7 @@ }, "node_modules/eris-sharder": { "version": "1.10.0", - "resolved": "git+ssh://git@github.com/esmBot/eris-sharder.git#edc1b3154604c3106a45c42ecf9b25703bc44498", + "resolved": "git+ssh://git@github.com/esmBot/eris-sharder.git#3b7366e5d99012ca0e3350e4d81f384b48911c2d", "license": "MIT", "dependencies": { "colors": "^1.1.2", @@ -1690,6 +1707,18 @@ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2158,6 +2187,43 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, + "node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "optional": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -3277,6 +3343,23 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, + "node_modules/tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "optional": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/tar-fs": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", @@ -3288,6 +3371,11 @@ "tar-stream": "^2.1.4" } }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, "node_modules/tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", @@ -3591,9 +3679,9 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "node_modules/ws": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.0.tgz", - "integrity": "sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.1.tgz", + "integrity": "sha512-2c6faOUH/nhoQN6abwMloF7Iyl0ZS2E9HGtsiLrWn0zOOMWlhtDmdf/uihDt6jnuCxgtwGBNy6Onsoy2s2O2Ow==", "engines": { "node": ">=8.3.0" }, @@ -4197,6 +4285,17 @@ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, + "better-sqlite3": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-7.4.1.tgz", + "integrity": "sha512-sk1kW3PsWE7W7G9qbi5TQxCROlQVR8YWlp4srbyrwN5DrLeamKfrm3JExwOiNSAYyJv8cw5/2HOfvF/ipZj4qg==", + "optional": true, + "requires": { + "bindings": "^1.5.0", + "prebuild-install": "^6.0.1", + "tar": "^6.1.0" + } + }, "bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", @@ -4317,9 +4416,9 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "caniuse-lite": { - "version": "1.0.30001240", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001240.tgz", - "integrity": "sha512-nb8mDzfMdxBDN7ZKx8chWafAdBp5DAAlpWvNyUGe5tcDWd838zpzDN3Rah9cjCqhfOKkrvx40G2SDtP0qiWX/w==", + "version": "1.0.30001241", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001241.tgz", + "integrity": "sha512-1uoSZ1Pq1VpH0WerIMqwptXHNNGfdl7d1cJUFs80CwQ/lVzdhTvsFZCeNFslze7AjsQnb4C85tzclPa1VShbeQ==", "dev": true, "peer": true }, @@ -4335,9 +4434,10 @@ } }, "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "optional": true }, "cliui": { "version": "5.0.0", @@ -4561,9 +4661,9 @@ "integrity": "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==" }, "electron-to-chromium": { - "version": "1.3.759", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.759.tgz", - "integrity": "sha512-nM76xH0t2FBH5iMEZDVc3S/qbdKjGH7TThezxC8k1Q7w7WHvIAyJh8lAe2UamGfdRqBTjHfPDn82LJ0ksCiB9g==", + "version": "1.3.761", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.761.tgz", + "integrity": "sha512-7a/wV/plM/b95XjTdA2Q4zAxxExTDKkNQpTiaU/nVT8tGCQVtX9NsnTjhALBFICpOB58hU6xg5fFC3CT2Bybpg==", "dev": true, "peer": true }, @@ -4599,7 +4699,7 @@ } }, "eris-sharder": { - "version": "git+ssh://git@github.com/esmBot/eris-sharder.git#edc1b3154604c3106a45c42ecf9b25703bc44498", + "version": "git+ssh://git@github.com/esmBot/eris-sharder.git#3b7366e5d99012ca0e3350e4d81f384b48911c2d", "from": "eris-sharder@github:esmBot/eris-sharder#eris-dev", "requires": { "colors": "^1.1.2", @@ -4958,6 +5058,15 @@ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "optional": true, + "requires": { + "minipass": "^3.0.0" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -5317,6 +5426,31 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "optional": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "optional": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "optional": true + }, "mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -6160,6 +6294,20 @@ } } }, + "tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "optional": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + }, "tar-fs": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", @@ -6169,6 +6317,13 @@ "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" + }, + "dependencies": { + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + } } }, "tar-stream": { @@ -6404,9 +6559,9 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "ws": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.0.tgz", - "integrity": "sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.1.tgz", + "integrity": "sha512-2c6faOUH/nhoQN6abwMloF7Iyl0ZS2E9HGtsiLrWn0zOOMWlhtDmdf/uihDt6jnuCxgtwGBNy6Onsoy2s2O2Ow==", "requires": {} }, "xtend": { diff --git a/package.json b/package.json index 594fd41..a58e34a 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "eslint": "^7.23.0" }, "optionalDependencies": { + "better-sqlite3": "^7.4.1", "bufferutil": "^4.0.1", "erlpack": "github:abalabahaha/erlpack", "mongoose": "^5.11.8", diff --git a/utils/database/sqlite.js b/utils/database/sqlite.js new file mode 100644 index 0000000..6fe592f --- /dev/null +++ b/utils/database/sqlite.js @@ -0,0 +1,127 @@ +const collections = require("../collections.js"); +const misc = require("../misc.js"); +const logger = require("../logger.js"); + +const sqlite3 = require("better-sqlite3"); +const connection = sqlite3(process.env.DB.replace("sqlite://", "")); + +exports.setup = async () => { + let counts; + try { + counts = connection.prepare("SELECT * FROM counts").all(); + } catch { + connection.prepare("CREATE TABLE counts ( command VARCHAR NOT NULL, count integer NOT NULL )").run(); + counts = []; + } + + if (!counts) { + for (const command of collections.commands.keys()) { + connection.prepare("INSERT INTO counts (command, count) VALUES (?, ?)").run(command, 0); + } + } else { + const exists = []; + for (const command of collections.commands.keys()) { + const count = connection.prepare("SELECT * FROM counts WHERE command = ?").get(command); + if (!count) { + connection.prepare("INSERT INTO counts (command, count) VALUES (?, ?)").run(command, 0); + } + exists.push(command); + } + + for (const { command } of counts) { + if (!exists.includes(command)) { + connection.prepare("DELETE FROM counts WHERE command = ?").run(command); + } + } + } +}; + +exports.stop = async () => { + connection.close(); +}; + +exports.fixGuild = async (guild) => { + let guildDB; + try { + guildDB = connection.prepare("SELECT * FROM guilds WHERE guild_id = ?").get(guild.id); + } catch { + connection.prepare("CREATE TABLE guilds ( guild_id VARCHAR(30) NOT NULL, tags text NOT NULL, prefix VARCHAR(15) NOT NULL, disabled text NOT NULL, tags_disabled integer NOT NULL DEFAULT 0 CHECK(tags_disabled IN (0,1)) )").run(); + } + if (!guildDB) { + logger.log(`Registering guild database entry for guild ${guild.id}...`); + return await this.addGuild(guild); + } +}; + +exports.addCount = async (command) => { + connection.prepare("UPDATE counts SET count = count + 1 WHERE command = ?").run(command); +}; + +exports.getCounts = async () => { + const counts = connection.prepare("SELECT * FROM counts").all(); + const countObject = {}; + for (const { command, count } of counts) { + countObject[command] = count; + } + return countObject; +}; + +exports.disableChannel = async (channel) => { + const guildDB = await this.getGuild(channel.guild.id); + connection.prepare("UPDATE guilds SET disabled = ? WHERE guild_id = ?").run(JSON.stringify([...JSON.parse(guildDB.disabled), channel.id]), channel.guild.id); + collections.disabledCache.set(channel.guild.id, [...JSON.parse(guildDB.disabled), channel.id]); +}; + +exports.enableChannel = async (channel) => { + const guildDB = await this.getGuild(channel.guild.id); + const newDisabled = JSON.parse(guildDB.disabled).filter(item => item !== channel.id); + connection.prepare("UPDATE guilds SET disabled = ? WHERE guild_id = ?").run(JSON.stringify(newDisabled), channel.guild.id); + collections.disabledCache.set(channel.guild.id, newDisabled); +}; + +exports.toggleTags = async (guild) => { + const guildDB = await this.getGuild(guild.id); + guildDB.tags_disabled = guildDB.tags_disabled ? 0 : 1; + connection.prepare("UPDATE guilds SET tags_disabled = ? WHERE guild_id = ?").run(guildDB.tags_disabled, guild.id); +}; + +exports.setTag = async (name, content, guild) => { + const guildDB = await this.getGuild(guild.id); + const tags = JSON.parse(guildDB.tags); + tags[name] = content; + connection.prepare("UPDATE guilds SET tags = ? WHERE guild_id = ?").run(JSON.stringify(tags), guild.id); +}; + +exports.removeTag = async (name, guild) => { + const guildDB = await this.getGuild(guild.id); + const tags = JSON.parse(guildDB.tags); + delete tags[name]; + connection.prepare("UPDATE guilds SET tags = ? WHERE guild_id = ?").run(JSON.stringify(tags), guild.id); +}; + +exports.setPrefix = async (prefix, guild) => { + connection.prepare("UPDATE guilds SET prefix = ? WHERE guild_id = ?").run(prefix, guild.id); + collections.prefixCache.set(guild.id, prefix); +}; + +exports.addGuild = async (guild) => { + const query = await this.getGuild(guild); + if (query) return query; + const guildObject = { + id: guild.id, + tags: JSON.stringify(misc.tagDefaults), + prefix: process.env.PREFIX, + disabled: "[]", + tagsDisabled: 0 + }; + connection.prepare("INSERT INTO guilds (guild_id, tags, prefix, disabled, tags_disabled) VALUES (@id, @tags, @prefix, @disabled, @tagsDisabled)").run(guildObject); + return guildObject; +}; + +exports.getGuild = async (query) => { + try { + return connection.prepare("SELECT * FROM guilds WHERE guild_id = ?").get(query); + } catch { + return; + } +}; diff --git a/utils/image.js b/utils/image.js index a1f4aa2..7e7afaa 100644 --- a/utils/image.js +++ b/utils/image.js @@ -143,7 +143,7 @@ const getIdeal = async () => { const controller = new AbortController(); // eslint-disable-line no-undef const timeout = setTimeout(() => { controller.abort(); - }, 2000); + }, 5000); try { const statusRequest = await fetch(`http://${address}:8080/status`, { signal: controller.signal }); clearTimeout(timeout); @@ -235,7 +235,7 @@ exports.getType = async (image, extraReturnTypes) => { return type; }; -exports.run = object => { +exports.run = (object) => { return new Promise((resolve, reject) => { if (process.env.API === "true") { // Connect to best image server diff --git a/utils/parseCommand.js b/utils/parseCommand.js index 660a1c6..bf98400 100644 --- a/utils/parseCommand.js +++ b/utils/parseCommand.js @@ -1,5 +1,5 @@ module.exports = (input, allowed) => { - input = input.split(" "); + if (typeof input === "string") input = input.split(/\s+/g); const args = { _: [] }; let curr = null; let concated = ""; @@ -18,6 +18,10 @@ module.exports = (input, allowed) => { } } else if (value.endsWith("\"")) { args[arg] += a.slice(0, -1); + } else if (value === "true") { + args[arg] = true; + } else if (value === "false") { + args[arg] = false; } else if (value !== "") { args[arg] = value; } else {