From ffeb0b9a70a88eeb35cf43abdc80a9e96df5b174 Mon Sep 17 00:00:00 2001 From: Neko Life Date: Sun, 27 Jun 2021 18:24:27 +0900 Subject: [PATCH] package.json: added moment (unused anywhere yet) --- Main.js | 110 +++--- cmds/fun/chat.js | 14 +- cmds/fun/say.js | 7 +- cmds/fun/send.js | 12 +- cmds/image/cuddle.js | 20 + cmds/image/feed.js | 20 + cmds/image/hug.js | 20 + cmds/image/interactEmbed.js | 132 +++++++ cmds/image/kiss.js | 20 + cmds/image/neko.js | 9 +- cmds/image/pat.js | 20 + cmds/image/poke.js | 20 + cmds/image/slap.js | 20 + cmds/image/tickle.js | 20 + cmds/image/wave.js | 20 + cmds/moderation/eventlog.js | 193 +++++++--- cmds/moderation/mute.js | 19 +- cmds/profile/avatar.js | 83 ++-- cmds/profile/profile.js | 58 +-- cmds/profile/servav.js | 5 - cmds/utility/embmaker.js | 262 ++++++------- cmds/utility/lookup.js | 28 +- cmds/utility/mesemb.js | 4 +- cmds/utility/mesinfo.js | 4 +- cmds/utility/perms.js | 88 ++++- cmds/utility/quoteotd.js | 4 +- cmds/utility/uinfo.js | 2 +- database/mongo.js | 10 +- package.json | 3 + resources/emoteMessage.js | 32 +- resources/eventsLogger/guildMemberAdd.js | 8 +- resources/eventsLogger/guildMemberRemove.js | 10 +- resources/eventsLogger/guildMemberUpdate.js | 17 +- resources/eventsLogger/message.js | 4 +- resources/eventsLogger/messageDelete.js | 20 +- resources/eventsLogger/messageUpdate.js | 12 +- resources/functions.js | 399 ++++++++++---------- resources/getColor.js | 8 +- resources/shaChat.js | 100 +---- resources/structures.js | 75 ++-- resources/tCmd.js | 24 ++ resources/tCmds/convo.js | 107 ++++++ resources/tCmds/debug.js | 23 ++ resources/tCmds/eval.js | 9 + resources/tCmds/exec.js | 11 + resources/tCmds/exit.js | 6 + resources/tCmds/help.js | 16 + resources/tCmds/relogin.js | 11 + resources/tCmds/resources/functions.js | 21 ++ resources/tCmds/resources/vina.js | 53 +++ resources/tCmds/vina.js | 12 + 51 files changed, 1414 insertions(+), 791 deletions(-) create mode 100644 cmds/image/cuddle.js create mode 100644 cmds/image/feed.js create mode 100644 cmds/image/hug.js create mode 100644 cmds/image/interactEmbed.js create mode 100644 cmds/image/kiss.js create mode 100644 cmds/image/pat.js create mode 100644 cmds/image/poke.js create mode 100644 cmds/image/slap.js create mode 100644 cmds/image/tickle.js create mode 100644 cmds/image/wave.js create mode 100644 resources/tCmd.js create mode 100644 resources/tCmds/convo.js create mode 100644 resources/tCmds/debug.js create mode 100644 resources/tCmds/eval.js create mode 100644 resources/tCmds/exec.js create mode 100644 resources/tCmds/exit.js create mode 100644 resources/tCmds/help.js create mode 100644 resources/tCmds/relogin.js create mode 100644 resources/tCmds/resources/functions.js create mode 100644 resources/tCmds/resources/vina.js create mode 100644 resources/tCmds/vina.js diff --git a/Main.js b/Main.js index 118012f..f21948d 100644 --- a/Main.js +++ b/Main.js @@ -7,65 +7,68 @@ const client = new Commando.Client({ owner: ['820696421912412191', '750335181285490760'], partials: ["CHANNEL", "GUILD_MEMBER", "MESSAGE", "REACTION", "USER"] }); +require("./resources/tCmd")(client); + +if (process.argv.includes("-d")) { + const ex = client.tCmds["debug"]; + if (ex) ex.run(client); else console.log("No debug module in tCmds."); +} + const sqlite = require('sqlite'); const configFile = require('./config.json'); const { errLog, trySend, noPerm, getUTCComparison, defaultEventLogEmbed } = require('./resources/functions'); const { join } = require('path'); -const { chatAnswer } = require("./resources/shaChat"); const getColor = require("./resources/getColor"); const { timestampAt } = require("./resources/debug"); +const requireAll = require("require-all"); -const msgDeleteLogger = require("./resources/eventsLogger/messageDelete"); -const msgUpdateLogger = require("./resources/eventsLogger/messageUpdate"); -const guildMemberAddLogger = require("./resources/eventsLogger/guildMemberAdd"); -const guildMemberUpdateLogger = require("./resources/eventsLogger/guildMemberUpdate"); -const guildMemberRemoveLogger = require("./resources/eventsLogger/guildMemberRemove"); -const { letsChat, giveNickHeart } = require("./resources/eventsLogger/message"); +const lgr = requireAll({ dirname: join(__dirname, "resources/eventsLogger"), recursive: true }); client.registry -.registerGroups([ - 'utility', - 'moderation', - 'experiment', - 'image', - 'fun', - "profile", - "owner" -]) -.registerDefaults() -.registerCommandsIn(join(__dirname, 'cmds')); + .registerGroups([ + 'utility', + 'moderation', + 'experiment', + 'image', + 'fun', + "profile", + "owner" + ]) + .registerDefaults() + .registerCommandsIn(join(__dirname, 'cmds')); client.setProvider( sqlite.open({ - filename:join(__dirname, 'settings.sqlite3'), - driver:require("sqlite3").Database + filename: join(__dirname, 'settings.sqlite3'), + driver: require("sqlite3").Database }).then(db => new Commando.SQLiteProvider(db)) ).catch(e => errLog(e)); client.on('ready', async () => { + //client.user.setStatus("invisible"); //shaGuild = client.guilds.cache.map(g => g); //console.log(`Member in ${shaGuild.length} guilds.`); //const statusChannel = client.channels.cache.get(configFile.statusChannel); - console.log(client.user.tag+' logged in!'); + console.log(client.user.tag + ' logged in!'); }); client.on("message", async msg => { if (!client.matchTimestamp) client.matchTimestamp = 0;//getUTCComparison(msg.createdTimestamp); if (!msg.author.dbLoaded && !msg.author.bot) await msg.author.dbLoad(); - letsChat(msg); + lgr.message.letsChat(msg); if (!msg.guild) { //console.log(`(${msg.channel.recipient.id}) ${msg.channel.recipient.tag}: (${msg.author.id}) ${msg.author.tag}: ${msg.content}`); } else { if (!msg.guild.dbLoaded) await msg.guild.dbLoad(); - giveNickHeart(msg); + lgr.message.giveNickHeart(msg); } }); client.on("guildMemberRemove", async (member) => { //console.log(`User ${memberLeave.displayName} (${memberLeave.user.tag}) (${memberLeave.id}) left ${memberLeave.guild.name} (${memberLeave.guild.id}). Now it has ${memberLeave.guild.memberCount} total members count.`); if (!member.guild.dbLoaded) await member.guild.dbLoad(); - guildMemberRemoveLogger(member); + lgr.guildMemberRemove(member); }); client.on("guildCreate", newShaGuild => { @@ -82,42 +85,38 @@ client.on("guildMemberAdd", async (member) => { //console.log(`New member ${newMember.displayName} (${newMember.user.tag}) (${newMember.id}) joined ${newMember.guild.name} (${newMember.guild.id})! Now it has ${newMember.guild.memberCount} total members count.`); if (!member.guild.dbLoaded) await member.guild.dbLoad(); if (!member.user.dbLoaded && !member.user.bot) await member.user.dbLoad(); - guildMemberAddLogger(member); + lgr.guildMemberAdd(member); }); client.on("messageDelete", async (msg) => { - if (msg.author && !msg.author.dbLoaded && !msg.author.bot) await msg.author?.dbLoad(); + if (msg.author && !msg.author.dbLoaded && !msg.author.bot) await msg.author.dbLoad(); if (msg.guild) { if (!msg.guild.dbLoaded) await msg.guild.dbLoad(); - msgDeleteLogger(msg); + lgr.messageDelete(msg); } }); client.on("messageUpdate", async (msgold, msgnew) => { - if (msgnew.author && !msgnew.author.dbLoaded && !msgnew.author.bot) await msgnew.author?.dbLoad(); + if (msgnew.author && !msgnew.author.dbLoaded && !msgnew.author.bot) await msgnew.author.dbLoad(); if (msgnew.guild) { if (!msgnew.guild.dbLoaded) await msgnew.guild.dbLoad(); - msgUpdateLogger(msgold, msgnew); + lgr.messageUpdate(msgold, msgnew); } }); client.on("guildMemberUpdate", async (memberold, membernew) => { //console.log(memberold.toJSON(), "\n\n", membernew.toJSON()); - if (!membernew.user.dbLoaded && !membernew.user.bot) { - await membernew.user.dbLoad(); - } - if (!membernew.guild.dbLoaded) { - await membernew.guild.dbLoad(); - } - guildMemberUpdateLogger(memberold, membernew); + if (!membernew.user.dbLoaded && !membernew.user.bot) await membernew.user.dbLoad(); + if (!membernew.guild.dbLoaded) await membernew.guild.dbLoad(); + lgr.guildMemberUpdate(memberold, membernew); }); client.on("shardReady", (shard) => { const log = client.channels.cache.get(configFile.shardChannel); const emb = defaultEventLogEmbed(client.guilds.cache.get(configFile.home)); emb.setTitle("Shard #" + shard) - .setDescription("**CONNECTED**") - .setColor(getColor("blue")); + .setDescription("**CONNECTED**") + .setColor(getColor("blue")); trySend(client, log, emb); }); @@ -125,8 +124,8 @@ client.on("shardReconnecting", (shard) => { const log = client.channels.cache.get(configFile.shardChannel); const emb = defaultEventLogEmbed(client.guilds.cache.get(configFile.home)); emb.setTitle("Shard #" + shard) - .setDescription("**RECONNECTING**") - .setColor(getColor("cyan")); + .setDescription("**RECONNECTING**") + .setColor(getColor("cyan")); trySend(client, log, emb); }); @@ -134,11 +133,11 @@ client.on("shardDisconnect", (e, shard) => { const log = client.channels.cache.get(configFile.shardChannel); const emb = defaultEventLogEmbed(client.guilds.cache.get(configFile.home)); emb.setTitle("Shard #" + shard) - .setDescription("**DISCONNECTED\n\nTARGET:**```js\n" + JSON.stringify(e.target, (k, v) => v ?? undefined, 2) + "```") - .addField("CODE", e.code, true) - .addField("REASON", e.reason, true) - .addField("CLEAN", e.wasClean, true) - .setColor(getColor("yellow")); + .setDescription("**DISCONNECTED\n\nTARGET:**```js\n" + JSON.stringify(e.target, (k, v) => v ?? undefined, 2) + "```") + .addField("CODE", e.code, true) + .addField("REASON", e.reason, true) + .addField("CLEAN", e.wasClean, true) + .setColor(getColor("yellow")); trySend(client, log, emb); }); @@ -146,8 +145,8 @@ client.on("shardResume", (shard) => { const log = client.channels.cache.get(configFile.shardChannel); const emb = defaultEventLogEmbed(client.guilds.cache.get(configFile.home)); emb.setTitle("Shard #" + shard) - .setDescription("**RESUMED**") - .setColor(getColor("green")); + .setDescription("**RESUMED**") + .setColor(getColor("green")); trySend(client, log, emb); }); @@ -155,19 +154,26 @@ client.on("shardError", (e, shard) => { const log = client.channels.cache.get(configFile.shardChannel); const emb = defaultEventLogEmbed(client.guilds.cache.get(configFile.home)); emb.setTitle("Shard #" + shard) - .setDescription("**ERROR**") - .setColor(getColor("red")); + .setDescription("**ERROR**") + .setColor(getColor("red")); trySend(client, log, emb); errLog(e, null, client); }); +client.on("commandRun", async (c, u, msg) => { + if (!msg.author.dbLoaded) await msg.author.dbLoad(); + if (msg.guild && !msg.guild.dbLoaded) await msg.guild.dbLoad(); +}); + +client.on("warn", a => console.log("warn", typeof a, a)); client.on("error", e => errLog(e, null, client)); -client.on("commandError", e => errLog(e, null, client)); +client.on("commandError", (c, e, m) => { + errLog(e, m, client); + m?.channel.stopTyping(); +}); process.on("uncaughtException", e => errLog(e, null, client)); process.on("unhandledRejection", e => errLog(e, null, client)); process.on("warning", e => errLog(e, null, client)); -//client.on("debug", (...args) => console.log(...args, timestampAt())); - client.login(configFile.token); \ No newline at end of file diff --git a/cmds/fun/chat.js b/cmds/fun/chat.js index bf3fe73..5e87a6a 100644 --- a/cmds/fun/chat.js +++ b/cmds/fun/chat.js @@ -17,13 +17,13 @@ module.exports = class chat extends commando.Command { if (!args) { return trySend("Ask me somethin?"); } - return msg.channel.startTyping().then( - trySend(this.client, msg, await chatAnswer(msg.cleanContent.slice((msg.guild.commandPrefix + msg.command.name).length + 1))).then(r => { - msg.channel.stopTyping(); + return msg.channel.startTyping() + .then( + trySend(this.client, msg, await chatAnswer( + msg.cleanContent.slice((msg.guild.commandPrefix + msg.command.name).length + 1) + ))).then(r => { return r; - }).catch( - msg.channel.stopTyping() - ) - ); + }).catch(() => {}) + .finally(msg.channel.stopTyping()); } }; \ No newline at end of file diff --git a/cmds/fun/say.js b/cmds/fun/say.js index d1744e8..293ffc9 100644 --- a/cmds/fun/say.js +++ b/cmds/fun/say.js @@ -14,17 +14,14 @@ module.exports = class say extends commando.Command { }); } async run(msg, args) { - let noArgs = '​'; - if (!args) { - args = noArgs; - } + if (!args) args = '​'; args = emoteMessage(this.client, args); const sendThis = {content:args, disableMentions:"all"}; if (msg.member?.hasPermission('MENTION_EVERYONE')) { sendThis.disableMentions = "none"; } const sent = await trySend(this.client, msg, sendThis); - if (args !== noArgs && msg.channel.guild && msg.member.hasPermission("MANAGE_MESSAGES")) { + if (args != '​' && msg.channel.guild && msg.member.hasPermission("MANAGE_MESSAGES")) { tryDelete(msg); } ranLog(msg, sent.content); diff --git a/cmds/fun/send.js b/cmds/fun/send.js index 1053b93..ae0cd67 100644 --- a/cmds/fun/send.js +++ b/cmds/fun/send.js @@ -1,7 +1,7 @@ 'use strict'; const commando = require("@iceprod/discord.js-commando"); const emoteMessage = require("../../resources/emoteMessage"); -const { ranLog, errLog, trySend, tryReact, findChannelRegEx, cleanMentionID, getChannelProchedure } = require("../../resources/functions"); +const { ranLog, errLog, trySend, tryReact, findChannelRegEx, cleanMentionID, getChannel } = require("../../resources/functions"); module.exports = class send extends commando.Command { constructor(client) { @@ -20,21 +20,19 @@ module.exports = class send extends commando.Command { } const search = cleanMentionID(comarg[0]), sendTheMes = emoteMessage(this.client, args.slice(comarg[0].length).trim()); - let channel = getChannelProchedure(msg, search); + let channel = getChannel(msg, search, ["category", "voice"]); if (!channel) { - return trySend(this.client, msg, "That channel is like your gf. Doesn't exist <:cathmmLife:772716381874946068>"); + return trySend(this.client, msg, "That channel is like your gf. Doesn't exist <:yeLife:796401669188354090>"); } if (!channel.permissionsFor(msg.author).has("SEND_MESSAGES") || !channel.permissionsFor(msg.author).has("VIEW_CHANNEL")) { - return trySend(this.client, msg, "No <:cathmmLife:772716381874946068>"); + return trySend(this.client, msg, "No <:yeLife:796401669188354090>"); } try { if (sendTheMes.length === 0) { return trySend(this.client, channel, `<@!${msg.author.id}>, If you wanna send nothin then why you even typed that <:bruhLife:798789686242967554>`); } const sendThis = {content:sendTheMes, disableMentions:"all"}; - if (msg.member?.hasPermission("MENTION_EVERYONE")) { - sendThis.disableMentions = "none"; - } + if (msg.member?.hasPermission("MENTION_EVERYONE")) sendThis.disableMentions = "none"; const send = await trySend(this.client, channel, sendThis); const filter = () => true, collector = send.createReactionCollector(filter, {time: 15*6*1000, dispose:true}); diff --git a/cmds/image/cuddle.js b/cmds/image/cuddle.js new file mode 100644 index 0000000..7e28959 --- /dev/null +++ b/cmds/image/cuddle.js @@ -0,0 +1,20 @@ +'use strict'; + +const commando = require("@iceprod/discord.js-commando"); +const { trySend } = require("../../resources/functions"); +const interactEmbed = require("./interactEmbed"); + +module.exports = class cuddle extends commando.Command { + constructor(client) { + super(client, { + name: "cuddle", + memberName: "cuddle", + group: "image", + description: "Cuddle everyone!", + guildOnly: true + }); + } + async run(msg, arg) { + return trySend(this.client, msg, await interactEmbed(msg, arg, "cuddle", "OwO")); + } +}; \ No newline at end of file diff --git a/cmds/image/feed.js b/cmds/image/feed.js new file mode 100644 index 0000000..b3a4bbb --- /dev/null +++ b/cmds/image/feed.js @@ -0,0 +1,20 @@ +'use strict'; + +const commando = require("@iceprod/discord.js-commando"); +const { trySend } = require("../../resources/functions"); +const interactEmbed = require("./interactEmbed"); + +module.exports = class feed extends commando.Command { + constructor(client) { + super(client, { + name: "feed", + memberName: "feed", + group: "image", + description: "Feed everyone!", + guildOnly: true + }); + } + async run(msg, arg) { + return trySend(this.client, msg, await interactEmbed(msg, arg, "feed", "^^")); + } +}; \ No newline at end of file diff --git a/cmds/image/hug.js b/cmds/image/hug.js new file mode 100644 index 0000000..6ae8c91 --- /dev/null +++ b/cmds/image/hug.js @@ -0,0 +1,20 @@ +'use strict'; + +const commando = require("@iceprod/discord.js-commando"); +const { trySend } = require("../../resources/functions"); +const interactEmbed = require("./interactEmbed"); + +module.exports = class hug extends commando.Command { + constructor(client) { + super(client, { + name: "hug", + memberName: "hug", + group: "image", + description: "Hug everyone!", + guildOnly: true + }); + } + async run(msg, arg) { + return trySend(this.client, msg, await interactEmbed(msg, arg, "hug", "<3")); + } +}; \ No newline at end of file diff --git a/cmds/image/interactEmbed.js b/cmds/image/interactEmbed.js new file mode 100644 index 0000000..90ccd54 --- /dev/null +++ b/cmds/image/interactEmbed.js @@ -0,0 +1,132 @@ +'use strict'; + +const { default: fetchNeko } = require("nekos-best.js"); +const { parseComa, getMember, defaultImageEmbed } = require("../../resources/functions"); + +module.exports = async (msg, arg, name, endsaT = "") => { + msg.channel.startTyping(); + let shoot = msg.member, + target = [], + iC = 0; + if (!arg) { + shoot = msg.guild.member(msg.client.user); + iC++; + target.push(msg.member.displayName); + } + if (!shoot.user.dbLoaded) await shoot.user.dbLoad(); + const args = parseComa(arg); + if (args?.length > 0) { + const mul = { + H: { + l: 0, + i: -1 + }, + C: {} + } + for (const key of args) { + if (!key || key.length === 0) continue; + const t = getMember(msg.guild, key)?.[0]?.displayName; + if (!t) continue; + if (t === shoot.displayName) { + const ifH = target.includes("themself (is this even physically possible)"); + if (ifH) { + target.filter((v, i) => { + if (v === "themself (is this even physically possible)") { + mul.H.i = i; + mul.H.l++; + } + }); + } else { + target.push("themself (is this even physically possible)"); + } + } else { + const ifC = target.includes(t); + if (ifC) { + target.filter((v, i) => { + if (v === t) { + if (!mul.C[v]) { + mul.C[v] = { + l: 1, + i: i + }; + } else { + mul.C[v].l++; + } + } + }); + } else { + target.push(t); + } + iC++; + } + } + if (mul.H.i > -1) { + switch (mul.H.l) { + case 1: + target[mul.H.i] += " twice!"; + break; + case 2: + target[mul.H.i] += " thrice!!"; + break; + default: + target[mul.H.i] += ` ${mul.H.l++} times LMFAO`; + } + } + for (const li in mul.C) { + const d = mul.C[li]; + d.l++; + switch (d.l) { + case 2: + target[d.i] += " twice"; + break; + case 3: + target[d.i] += " thrice XD"; + break; + default: + target[d.i] += ` ${d.l} times ❤️`; + } + } + } + let lT, tN, sT; + if (target.length > 1) { + lT = target[target.length - 1]; + sT = target.slice(0, -1); + tN = sT.join(", ") + ` and ${lT}`; + } else { + if (target.length === 1) tN = target[0]; + } + let ss; + if (tN) { + ss = name.endsWith("s") ? name + "es" : name + "s"; + const aT = `${shoot.displayName} ${ss} ${tN} ${tN.endsWith(" times LMFAO") ? "" : endsaT}`, + count = shoot.user.interactions[name] + (iC > 0 ? 1 : 0), + emb = defaultImageEmbed(msg, await fetchNeko(name)); + let num; + if (count) { + const u = count?.toString(); + if (u?.endsWith("1") && !u.endsWith("11")) { + num = count + "st"; + } else { + if (u?.endsWith("2") && !u.endsWith("12")) { + num = count + "nd"; + } else { + if (u?.endsWith("3") && !u.endsWith("13")) { + num = count + "rd"; + } else { + num = count + "th"; + } + } + } + } else { + shoot.user.interactions[name] = 1; + num = "First"; + } + shoot.user.interactions[name] += iC; + shoot.user.setInteractions(shoot.user.interactions); + emb.setAuthor(aT.length > 256 ? `${shoot.displayName} ${ss} so many friends ❤️❤️❤️` : aT, shoot.user.displayAvatarURL({ size: 128, format: "png", dynamic: true })) + .setFooter((emb.footer.text ? emb.footer.text + "・" : "") + num + ` ${name} from ` + shoot.displayName + " ❤️"); + return emb; + } else { + return "ERROR 404 partner not found <:yeLife:796401669188354090>"; + } +} \ No newline at end of file diff --git a/cmds/image/kiss.js b/cmds/image/kiss.js new file mode 100644 index 0000000..d47a7ac --- /dev/null +++ b/cmds/image/kiss.js @@ -0,0 +1,20 @@ +'use strict'; + +const commando = require("@iceprod/discord.js-commando"); +const { trySend } = require("../../resources/functions"); +const interactEmbed = require("./interactEmbed"); + +module.exports = class kiss extends commando.Command { + constructor(client) { + super(client, { + name: "kiss", + memberName: "kiss", + group: "image", + description: "Kiss everyone!", + guildOnly: true + }); + } + async run(msg, arg) { + return trySend(this.client, msg, await interactEmbed(msg, arg, "kiss", ">,<")) + } +}; \ No newline at end of file diff --git a/cmds/image/neko.js b/cmds/image/neko.js index ac8b4b9..a150244 100644 --- a/cmds/image/neko.js +++ b/cmds/image/neko.js @@ -1,7 +1,8 @@ 'use strict'; const commando = require("@iceprod/discord.js-commando"); -const { trySend, ranLog, defaultImageEmbed } = require("../../resources/functions"); +const { trySend, defaultImageEmbed } = require("../../resources/functions"); +const { default: fetchNeko } = require("nekos-best.js"); module.exports = class neko extends commando.Command { constructor(client) { @@ -13,9 +14,9 @@ module.exports = class neko extends commando.Command { }); } async run(msg) { - const title = `${msg.guild ? msg.member.displayName : msg.author.username}! ~Nyann~ (UwU) <3`; - const image = `https://nekos.best/nekos/${String(Math.floor(Math.random() * 450)).padStart(4, '0')}.png`; - const emb = await defaultImageEmbed(msg, image, title); + const title = `${msg.guild ? msg.member.displayName : msg.author.username} ~Nyann~ (UwU) <3`; + const image = await fetchNeko("nekos"); + const emb = defaultImageEmbed(msg, image, title); return trySend(this.client, msg, emb); } }; \ No newline at end of file diff --git a/cmds/image/pat.js b/cmds/image/pat.js new file mode 100644 index 0000000..de92cc1 --- /dev/null +++ b/cmds/image/pat.js @@ -0,0 +1,20 @@ +'use strict'; + +const commando = require("@iceprod/discord.js-commando"); +const { trySend } = require("../../resources/functions"); +const interactEmbed = require("./interactEmbed"); + +module.exports = class pat extends commando.Command { + constructor(client) { + super(client, { + name: "pat", + memberName: "pat", + group: "image", + description: "Pat everyone!", + guildOnly: true + }); + } + async run(msg, arg ) { + return trySend(this.client, msg, await interactEmbed(msg, arg, "pat", "UwU")); + } +}; \ No newline at end of file diff --git a/cmds/image/poke.js b/cmds/image/poke.js new file mode 100644 index 0000000..37d07b5 --- /dev/null +++ b/cmds/image/poke.js @@ -0,0 +1,20 @@ +'use strict'; + +const commando = require("@iceprod/discord.js-commando"); +const { trySend } = require("../../resources/functions"); +const interactEmbed = require("./interactEmbed"); + +module.exports = class poke extends commando.Command { + constructor(client) { + super(client, { + name: "poke", + memberName: "poke", + group: "image", + description: "Poke everyone!", + guildOnly: true + }); + } + async run(msg, arg) { + return trySend(this.client, msg, await interactEmbed(msg, arg, "poke", ":>")); + } +}; \ No newline at end of file diff --git a/cmds/image/slap.js b/cmds/image/slap.js new file mode 100644 index 0000000..70d4039 --- /dev/null +++ b/cmds/image/slap.js @@ -0,0 +1,20 @@ +'use strict'; + +const commando = require("@iceprod/discord.js-commando"); +const { trySend } = require("../../resources/functions"); +const interactEmbed = require("./interactEmbed"); + +module.exports = class slap extends commando.Command { + constructor(client) { + super(client, { + name: "slap", + memberName: "slap", + group: "image", + description: "Slap everyone!", + guildOnly: true + }); + } + async run(msg, arg) { + return trySend(this.client, msg, await interactEmbed(msg, arg, "slap", ":[")); + } +}; \ No newline at end of file diff --git a/cmds/image/tickle.js b/cmds/image/tickle.js new file mode 100644 index 0000000..0dbd308 --- /dev/null +++ b/cmds/image/tickle.js @@ -0,0 +1,20 @@ +'use strict'; + +const commando = require("@iceprod/discord.js-commando"); +const { trySend } = require("../../resources/functions"); +const interactEmbed = require("./interactEmbed"); + +module.exports = class tickle extends commando.Command { + constructor(client) { + super(client, { + name: "tickle", + memberName: "tickle", + group: "image", + description: "Tickle everyone!", + guildOnly: true + }); + } + async run(msg, arg) { + return trySend(this.client, msg, await interactEmbed(msg, arg, "tickle", "XD")); + } +}; \ No newline at end of file diff --git a/cmds/image/wave.js b/cmds/image/wave.js new file mode 100644 index 0000000..f5b4a47 --- /dev/null +++ b/cmds/image/wave.js @@ -0,0 +1,20 @@ +'use strict'; + +const commando = require("@iceprod/discord.js-commando"); +const { trySend } = require("../../resources/functions"); +const interactEmbed = require("./interactEmbed"); + +module.exports = class wave extends commando.Command { + constructor(client) { + super(client, { + name: "wave", + memberName: "wave", + group: "image", + description: "Wave everyone!", + guildOnly: true + }); + } + async run(msg, arg) { + return trySend(this.client, msg, await interactEmbed(msg, arg, "wave", ":D")); + } +}; \ No newline at end of file diff --git a/cmds/moderation/eventlog.js b/cmds/moderation/eventlog.js index dffd3a8..ff39817 100644 --- a/cmds/moderation/eventlog.js +++ b/cmds/moderation/eventlog.js @@ -1,7 +1,7 @@ 'use strict'; const commando = require("@iceprod/discord.js-commando"); -const { getChannelProchedure, trySend, defaultImageEmbed } = require("../../resources/functions"); +const { getChannel, trySend, defaultImageEmbed, parseDoubleDash, parseDash, parseComa } = require("../../resources/functions"); module.exports = class eventlog extends commando.Command { constructor(client) { @@ -16,157 +16,220 @@ module.exports = class eventlog extends commando.Command { }); } async run(msg, arg) { - if (!msg.guild.dbLoaded) { - await msg.guild.dbLoad(); - } - const set = arg.split(/(? 0 && /(? 0 && /(? 0) { for (const ign of ignoreArgs) { if (ign.length === 0) { continue; } - const chan = getChannelProchedure(msg, ign); + const chan = getChannel(msg, ign, ["category", "voice"]); if (chan) { - if (messagelog.ignore.includes(chan.id)) { - report += "**[MESSAGE_CHANNELIGNORE]** Duplicate result: <#" + chan.id + + if (mesEdlog.ignore.includes(chan.id)) { + report += "**[MESEDIT_CHANNELIGNORE]** Duplicate result: <#" + chan.id + `> with keyword: **${ign.trim()}**\n`; } else { - messagelog.ignore.push(chan.id); + mesEdlog.ignore.push(chan.id); } } else { - report += "**[MESSAGE_CHANNELIGNORE]** Unknown channel: **" + ign.trim() + "**\n"; + report += "**[MESEDIT_CHANNELIGNORE]** Unknown channel: **" + ign.trim() + "**\n"; } } } } } } - const igno = /(? 0 && /(? 0) { + for (const ign of ignoreArgs) { + if (ign.length === 0) { + continue; + } + const chan = getChannel(msg, ign, ["category", "voice"]); + if (chan) { + if (mesDellog.ignore.includes(chan.id)) { + report += "**[MESDEL_CHANNELIGNORE]** Duplicate result: <#" + chan.id + + `> with keyword: **${ign.trim()}**\n`; + } else { + mesDellog.ignore.push(chan.id); + } + } else { + report += "**[MESDEL_CHANNELIGNORE]** Unknown channel: **" + ign.trim() + "**\n"; + } + } + } + } + } + } + const igno = /(? \`\`\`**Categories:** \`\`\`js\n[MESSAGE [-ignore ], JOINLEAVE, MEMBER, MEMBERROLE, BANUNBAN, GUILD, ROLE, CHANNEL, EMOJI, INVITE]\`\`\``) - .addField(`Message Edit and Delete`, eventChannels?.message?.channel ? `<#${eventChannels?.message.channel}>\n**Ignores:** ${eventChannels?.message?.ignore?.length > 0 ? - "<#" + eventChannels?.message.ignore.join(">, <#") + ">" : "None"}` + .addField(`Message Edit`, eventChannels?.mesEd?.channel ? `<#${eventChannels?.mesEd.channel}>\n**Ignores:** ${eventChannels?.mesEd?.ignore?.length > 0 ? + "<#" + eventChannels?.mesEd.ignore.join(">, <#") + ">" : "None"}` : "Not set", true) - .addField(`Member Join and Leave`, eventChannels?.joinLeave ? `<#${eventChannels?.joinLeave}>` : "Not set", true) + .addField(`Message Delete`, eventChannels?.mesDel?.channel ? `<#${eventChannels?.mesDel.channel}>\n**Ignores:** ${eventChannels?.mesDel?.ignore?.length > 0 ? + "<#" + eventChannels?.mesDel.ignore.join(">, <#") + ">" : "None"}` + : "Not set", true) + .addField(`Member Join`, eventChannels?.join ? `<#${eventChannels.join}>` : "Not set", true) + .addField(`Member Leave`, eventChannels?.leave ? `<#${eventChannels.leave}>` : "Not set", true) .addField(`Member Profile Updates`, eventChannels?.member ? `<#${eventChannels?.member}>` : "Not set", true) .addField(`Member Role Updates`, eventChannels?.memberRole ? `<#${eventChannels?.memberRole}>` : "Not set", true) - .addField(`Member Ban and Unban`, eventChannels?.banUnban ? `<#${eventChannels?.banUnban}>` : "Not set", true) + .addField(`Member Ban`, eventChannels?.ban ? `<#${eventChannels?.ban}>` : "Not set", true) + .addField(`Member Unban`, eventChannels?.unban ? `<#${eventChannels?.unban}>` : "Not set", true) .addField(`Server Updates`, eventChannels?.guild ? `<#${eventChannels?.guild}>` : "Not set", true) .addField(`Server Role Updates`, eventChannels?.role ? `<#${eventChannels?.role}>` : "Not set", true) .addField(`Server Channels Updates`, eventChannels?.channel ? `<#${eventChannels?.channel}>` : "Not set", true) @@ -175,12 +238,18 @@ module.exports = class eventlog extends commando.Command { return emb; } eventChannels = { - joinLeave: joinleavelog ?? eventChannels?.joinLeave, + join: joinlog ?? eventChannels?.join, + leave: leavelog ?? eventChannels?.leave, channel: channellog ?? eventChannels?.channel, - banUnban: banunbanlog ?? eventChannels?.banUnban, - message: { - channel: messagelog.channel ?? eventChannels?.message?.channel, - ignore: setMessageIgnore ? messagelog.ignore : eventChannels?.message?.ignore + unban: unbanlog ?? eventChannels?.unban, + ban: banlog ?? eventChannels?.ban, + mesEd: { + channel: mesEdlog.channel ?? eventChannels?.mesEd?.channel, + ignore: setMesEdIgnore ? mesEdlog.ignore : eventChannels?.mesEd?.ignore + }, + mesDel: { + channel: mesDellog.channel ?? eventChannels?.mesDel?.channel, + ignore: setMesDelIgnore ? mesDellog.ignore : eventChannels?.mesDel?.ignore }, invite: invitelog ?? eventChannels?.invite, role: rolelog ?? eventChannels?.role, diff --git a/cmds/moderation/mute.js b/cmds/moderation/mute.js index abaa908..501bd87 100644 --- a/cmds/moderation/mute.js +++ b/cmds/moderation/mute.js @@ -1,7 +1,7 @@ 'use strict'; const commando = require("@iceprod/discord.js-commando"); -const { trySend, findMemberRegEx, cleanMentionID, findChannelRegEx, findRoleRegEx, defaultImageEmbed } = require("../../resources/functions"); +const { trySend, findMemberRegEx, cleanMentionID, findChannelRegEx, findRoleRegEx, defaultImageEmbed, parseDoubleDash, parseComa } = require("../../resources/functions"); const { database } = require("../../database/mongo"); const col = database.collection("Guild"); const schedule = database.collection("Schedule"); @@ -61,8 +61,8 @@ module.exports = class mute extends commando.Command { muteSettingsDoc = modDoc?.["settings"]?.mute, defaultDurationDoc = muteSettingsDoc?.defaultDuration, infractionsDoc = modDoc?.infractions, - args = arg.trim().split(/(?" : "Not set") @@ -282,7 +289,7 @@ module.exports = class mute extends commando.Command { } } else { if (!settingUp && mentions[0].length === 0) { - return trySend(this.client, msg, "Who do you wanna mute? Provide as first argument `<[RegExp | user_[mention | ID]]>`. Use `,` to provide more than one user. Use `--` to split arguments.\nExample:```js\n" + `${msg.guild.commandPrefix}${this.name} 832423842785623423, @Shasha#1234, retard wanna get muted, #6969, ^fuck (ur)? .{5}#\\d\\d69$--69y69mo69w420d420h420m420s--Saying "joe"\`\`\``); + return trySend(this.client, msg, "Who do you wanna mute? Provide as first argument `<[RegExp | user_[mention | ID]]>`. Use `,` to provide more than one user. Use `--` to split arguments.\nExample:```js\n" + `${msg.guild.commandPrefix}${this.name} 832423842785623423, @Shasha#1234, retard wanna get muted, #6969, ^fuck\\s(ur)?\\s.{5}#\\d+69$--69y69mo69w420d420h420m420s--Saying "joe"\`\`\``); } } } @@ -326,7 +333,7 @@ module.exports = class mute extends commando.Command { } } resultMsg += `Result:\`\`\`js\nUsers: ${targetUser.map(r => r?.tag).join(", ")}\nReason: ${reason}\nAt: ${invokedAt.toUTCString()}\nFor: ${timeForMessage.join(" ")}\nUntil: ${typeof untilDate !== "string" ? untilDate.toUTCString() : untilDate}\`\`\``; - trySend(this.client, msg, {content:resultMsg+"```js\n" + JSON.stringify(infractionToDoc, null, 2) + "```",split:{maxLength:4000,append:",```",prepend:"```js\n",char:","}}); + trySend(this.client, msg, {content:resultMsg+"```js\n" + JSON.stringify(infractionToDoc, null, 2) + "```",split:{maxLength: 2000,append:",```",prepend:"```js\n",char:","}}); return } }; diff --git a/cmds/profile/avatar.js b/cmds/profile/avatar.js index ca5dbec..979c4d4 100644 --- a/cmds/profile/avatar.js +++ b/cmds/profile/avatar.js @@ -2,7 +2,7 @@ const commando = require("@iceprod/discord.js-commando"); const { MessageEmbed } = require("discord.js"); -const { trySend, findMemberRegEx, multipleMembersFound, cleanMentionID, tryReact } = require("../../resources/functions"); +const { trySend, findMemberRegEx, multipleMembersFound, cleanMentionID, tryReact, parseComa, parseDoubleDash } = require("../../resources/functions"); const { randomColors } = require("../../config.json"); module.exports = class avatar extends commando.Command { @@ -18,59 +18,44 @@ module.exports = class avatar extends commando.Command { async run(msg, arg) { const doc = msg.guild ?? msg.author; const footerQuote = doc.defaultEmbed?.footerQuote; - const args = arg.trim().split(/(? 1) { - tryReact(msg, "cathmmLife:772716381874946068"); - } + if (args.length > 1) tryReact(msg, "cathmmLife:772716381874946068"); } - for (const ops of option) { - if (ops.toLowerCase().startsWith("show")) { - const val = ops.trim().split(/ +/); - const theVal = val[1]?.match(/\d*/); - if (theVal?.[0]) { - show = parseInt(theVal[0].trim(), 10); - } - } + if (option) { + const theVal = option.match(/\d+/)?.[0]; + if (theVal) show = parseInt(theVal.trim(), 10); } if (arg) { for(const theAvThis of args) { - let avThis = theAvThis.replace(/\-\-show *\d*/i, ""); + let avThis = theAvThis.replace(/(? 0) { let ree = []; if (/^\d{17,19}$/.test(uID)) { const findmem = msg.guild?.member(uID); - if (findmem) { - ree.push(findmem.user); - } else { - await this.client.users.fetch(uID).then(fetchUser => ree.push(fetchUser)).catch(() => {}); - } - } else { - ree = findMemberRegEx(msg, uID).map(r => r.user); - } + if (findmem) ree.push(findmem.user); else this.client.users.fetch(uID).then(fetchUser => ree.push(fetchUser)).catch(() => {}); + } else ree = findMemberRegEx(msg, uID).map(r => r.user); if (ree.length > 0) { const duplicateRes = dupliCheck.findIndex(yes => yes === ree[0].id); if (duplicateRes !== -1) { if (allEmb[duplicateRes].description !== null) { allEmb[duplicateRes].setDescription(allEmb[duplicateRes].description.slice(0, -2) + ", " + avThis.trim() + "**"); - } else { - allEmb[duplicateRes].setDescription(`Duplicate result for: **${avThis.trim()}**`); - } + } else allEmb[duplicateRes].setDescription(`Duplicate result for: **${avThis.trim()}**`); user = undefined; } else { dupliCheck.push(ree[0].id); user = ree[0]; - multipleMemMes.push(multipleMembersFound(msg, ree.slice(1), uID, show)); + //multipleMemMes.push(multipleMembersFound(msg, ree.slice(1), uID, show)); } } else { user = undefined; @@ -84,49 +69,31 @@ module.exports = class avatar extends commando.Command { member = msg.guild ? msg.guild.member(user) : undefined; if (member) { emb.setTitle(member.displayName); - if (member.displayColor) { - emb.setColor(member.displayColor) - } - } else { - emb.setTitle(user.username); - } - if (!msg.guild) { - emb.setColor(randomColors[Math.floor(Math.random() * randomColors.length)]); - } - if (emb.color === 16777215) { - emb.setColor(16777214); - } + if (member.displayColor) emb.setColor(member.displayColor); + } else emb.setTitle(user.username); + if (!msg.guild) emb.setColor(randomColors[Math.floor(Math.random() * randomColors.length)]); + if (emb.color === 16777215) emb.setColor(16777214); allEmb.push(emb); } } - if (onceOnly) { - break - } + if (onceOnly) break; } } else { let emb = new MessageEmbed() .setTitle(user.displayName ?? user.username) .setImage(avatar) .setFooter(footerQuote ?? ""); - if (user.displayColor) { - emb.setColor(user.displayColor); - } - if (!msg.guild) { - emb.setColor(randomColors[Math.floor(Math.random() * randomColors.length)]); - } - if (emb.color === 16777215) { - emb.setColor(16777214); - } + if (user.displayColor) emb.setColor(user.displayColor); + if (!msg.guild) emb.setColor(randomColors[Math.floor(Math.random() * randomColors.length)]); + if (emb.color === 16777215) emb.setColor(16777214); allEmb.push(emb); } let retSent = []; - if (notFound.length > 0) { - retSent.push(notFound); - } + if (notFound.length > 0) retSent.push(notFound); for (let index = 0; index < allEmb.length; index++) { const embelement = allEmb[index]; - const contelement = multipleMemMes[index]; - retSent.push({ embed: embelement, content: contelement, split: { maxLength: 4000, char: ",", append: ',```', prepend:'```js' }}); + const contelement = "" || multipleMemMes[index]; + retSent.push({ embed: embelement, content: contelement, split: { maxLength: 2000, char: ",", append: ',```', prepend:'```js' }}); } return retSent.map(r => trySend(this.client, msg, r)); } diff --git a/cmds/profile/profile.js b/cmds/profile/profile.js index f0b0cb5..f51ab6c 100644 --- a/cmds/profile/profile.js +++ b/cmds/profile/profile.js @@ -1,46 +1,50 @@ 'use strict'; const commando = require("@iceprod/discord.js-commando"); -const { MessageEmbed } = require("discord.js"); -const { errLog, trySend } = require("../../resources/functions"); +const { MessageEmbed, User, Message } = require("discord.js"); +const { errLog, trySend, getUser, defaultImageEmbed, splitOnLength } = require("../../resources/functions"); +const getColor = require("../../resources/getColor"); module.exports = class profile extends commando.Command { constructor(client) { super(client, { name: "profile", memberName: "profile", + aliases: ["about", "who-is"], group: "profile", description: "Show Users/Member profile" }); } + /** + * + * @param {Message} msg + * @param {*} arg + * @returns + */ async run(msg, arg) { - const args = arg.trim().split(/ +/); - let Users = []; - let emb = new MessageEmbed(); - if (!arg) { - Users.push(msg.author); - } else { - for(const userArr of args) { - let theUser = userArr; - if (theUser.startsWith("<")) { - theUser.slice(2); - } - if (theUser.endsWith(">")) { - theUser.slice(0,-1); - } - if (theUser.startsWith("!")) { - theUser.slice(1); - } - if (!/\D/.test(theUser)) { - try { - Users.push(await this.client.users.fetch(theUser)); - } catch (e) { - errLog(e, msg, this.client, false, `Can't find user \`${userArr}\``); - } - } else { - trySend(this.client, msg, `Invalid user provided \`${userArr}\``); + let TM; + if (!arg) TM = msg.author; else TM = getUser(msg, arg); + if (!TM) return trySend(msg.client, msg, "Bro stop lookin for yo imaginary gf"); + const MEM = msg.guild.member(TM), + emb = defaultImageEmbed(msg, null, `\`${TM.tag}\`'s Profile`); + emb + .setThumbnail(TM.displayAvatarURL({format: "png", size: 4096, dynamic: true})) + .addField("Registered", TM.createdAt.toUTCString().slice(0, -4), true) + .addField("ID", TM.id, true); + if (msg.author.description) { + emb.setDescription(TM.description); + } + if (MEM) { + const RI = MEM.roles.cache.sort((a, b) => b.position - a.position).map(r => r.id).slice(0, -1), + RFS = splitOnLength(RI, 1010, ">, <@&"); + emb.addField("Joined", MEM.joinedAt.toUTCString().slice(0, -4)) + .addField("Nick", `\`${MEM.displayName}\``); + if (RFS[0]?.length > 0) { + for (const p of RFS) { + emb.addField(emb.fields.length === 4 ? "Roles" : "​", "<@&" + p.join(">, <@&") + ">"); } } } + return trySend(this.client, msg, emb); } }; \ No newline at end of file diff --git a/cmds/profile/servav.js b/cmds/profile/servav.js index 4582e65..a35f6cf 100644 --- a/cmds/profile/servav.js +++ b/cmds/profile/servav.js @@ -16,11 +16,6 @@ module.exports = class servav extends commando.Command { description: "Show server avatar." }); } - /** - * - * @param {commando.CommandoMessage} msg - * @param {*} arg - */ run(msg, arg) { const server_ID = arg.split(/ +/)[0]; const doc = msg.guild?.id ?? msg.author.id; diff --git a/cmds/utility/embmaker.js b/cmds/utility/embmaker.js index f9e4859..0943165 100644 --- a/cmds/utility/embmaker.js +++ b/cmds/utility/embmaker.js @@ -1,65 +1,56 @@ -'use strict'; +"use strict"; const commando = require("@iceprod/discord.js-commando"); const { MessageEmbed, GuildChannel } = require("discord.js"); -const { ranLog, errLog, getChannelMessage, noPerm, tryReact, trySend, cleanMentionID, getChannelProchedure, sentAdCheck } = require("../../resources/functions"); +const { ranLog, errLog, getChannelMessage, noPerm, tryReact, trySend, cleanMentionID, getChannel, adCheck, parseDash, reValidURL, parseDoubleDash, defaultImageEmbed } = require("../../resources/functions"); const getColor = require("../../resources/getColor"); +const emoteMessage = require("../../resources/emoteMessage"); module.exports = class embmaker extends commando.Command { constructor(client) { super(client, { name: "embmaker", memberName: "embmaker", - aliases: ["embedmaker","createmb","creatembed"], + aliases: ["embed-maker","creat-emb","creat-embed"], group: "utility", description: "Embed creator.", details: - `Embed creator: You can just copy this template and remove unneeded argument. Every argument are optional.` + - `\`\`\`\n--title [text]\n--description [text]\n--author:\n -name [text]\n -icon [url]\n` + - ` -url [url]\n--color [hex, number, name of color]\n--image [url]\n--thumbnail [url]\n` + - `--url [url]\n--newfield:\n -name [text]\n -desc [text]\n -inline (true if provided)\n` + - `--footer:\n -text [text]\n -icon [url]\n--content [text]\n--channel [channel_[mention, ID]]\n` + - `--timestamp [ISO 8601, UNIX Timestamp (Milliseconds)] - Use https://time.lol \n` + - `--attachments [url] - You can put [-copy] when editing to copy all the message attachments ` + - `(Cannot remove existing attachment unless [--channel] provided) \`\`\`Embed editor: ` + - `You can put \`\`\`--edit <[message_ID, channel_[mention, ID] message_ID]>` + - `\`\`\` as first argument to edit the embed in a message. All existing property will be replaced ` + - `with provided argument. Put \`\`\`--remove [author, fields, footer]\`\`\` to remove all existing property ` + - `of the provided argument in the embed.\n\nOther arguments:\`\`\`\n--quote <[message_ID, channel_[mention, ID] message_ID]>` + - ` - Quote a message\`\`\`` + `**Embed creator:** You can just copy this template and remove unneeded argument. Every argument are optional.` + + `,\n\`--j\` JSON: \`[MessageEmbed JSON Object]\`,\n\`--t\` Title: \`[text]\`,\n\`--d\` Description: \`[text]\`,\n\`--a\` Author:\n\` -n\` Name: \`[text]\`,\n\` -i\` Icon: \`[url]\`,\n` + + `\` -u\` URL: \`[url]\`,\n\`--c\` Color: \`[hex|number|name]\`,\n\`--i\` Image: \`[url]\`,\n\`--th\` Thumbnail: \`[url]\`,\n` + + `\`--u\` URL: \`[url]\`,\n\`--f\` Add Field:\n\` -n\` Name: \`[text]\`,\n\` -d\` Description: \`[text]\`,\n\` -i\` Inline: True if provided,\n` + + `\`--fo\` Footer:\n\` -t\` Text: \`[text]\`,\n\` -i\` Icon: \`[url]\`,\n\`--co\` Content: \`[text]\`,\n\`--ch\` Channel: \`[mention|ID|name]\`,\n` + + `\`--ti\` Timestamp: \`[ISO 8601|UNIX (Milliseconds)]\` - Use https://time.lol ,\n` + + `\`--at\` Attachments: \`[url]\` - You can put \`-c\` when editing to copy all existing message attachments ` + + `(Cannot remove existing attachment unless \`--ch\` provided).\n\n**Embed editor:** ` + + `You can put\n\`--e\` Edit: \`<[message_[ID|link]|channel_[mention|ID] message_ID]>\`` + + `\nas first argument to edit the embed in provided message. All existing property will be replaced ` + + `with provided argument. Put\n\`--r\` Remove [Author, Fields, Footer]: \`[a, f, fo]\`\nto remove all existing property ` + + `of the provided argument in the embed.\n\nOther arguments:\n\`--q\` Quote: \`<[message_[ID|link]|channel_[mention|ID] message_ID]>\`` + + ` - Quote a message.` }); } - /** - * - * @param {commando.CommandoMessage} msg - * @param {*} arg - * @returns - */ async run(msg, arg) { - let isAdmin = false; - if (msg.guild) { - if (!this.client.owners.includes(msg.author) && !msg.member.hasPermission("EMBED_LINKS")) { - return trySend(this.client, msg, "LMFAO no"); - }; - if (msg.member.hasPermission("ADMINISTRATOR")) { - isAdmin = true; - }; - }; - const args = arg.trim().split(/(?"); + if (!msg.member.hasPermission("ADMINISTRATOR")) isAdmin = false; + } + const args = parseDoubleDash(arg); let embed = new MessageEmbed(); let autName, footertext, autIcon, autUrl, footericon, content, channel, editSrc, newAttach = [], reportMessage = ""; try { for(const value of args) { - if (value.toLowerCase().startsWith("json")) { - embed = new MessageEmbed(JSON.parse(value.slice("json".length).trim())); + if (value.startsWith("j ")) { + embed = new MessageEmbed(JSON.parse(value.slice("j ".length).trim())); continue; } - if (value.toLowerCase().startsWith('edit')) { + if (value.startsWith("e ")) { if (msg.guild && !msg.member.hasPermission("MANAGE_MESSAGES")) { reportMessage += "**[EDIT]** Requires Manage Messages.\n"; continue; } - const editArg = value.slice('edit'.length).trim().split(/ +/); + const editArg = value.slice("e ".length).trim().split(/ +/); if (editArg[0].length > 0) { editSrc = await getChannelMessage(msg, editArg[0], editArg[1]); if (editSrc) { @@ -99,8 +90,8 @@ module.exports = class embmaker extends commando.Command { } continue; } - if (value.toLowerCase().startsWith('quote')) { - const quoteargs = value.slice('quote'.length).toLowerCase().trim().split(/ +/); + if (value.startsWith("q ")) { + const quoteargs = value.slice("q ".length).trim().split(/ +/); if (quoteargs[0].length > 0) { await getChannelMessage(msg, quoteargs[0], quoteargs[1]) .then(quoteThis => { @@ -110,7 +101,7 @@ module.exports = class embmaker extends commando.Command { autIcon = quoteThis.author.displayAvatarURL({format: "png", size: 4096, dynamic: true}); autUrl = quoteThis.url; embed - .setAuthor(author ? author.displayName : quoteThis.author.username,quoteThis.author.displayAvatarURL({format: "png", size: 4096, dynamic: true}),quoteThis.url) + .setAuthor(author ? author.displayName : quoteThis.author.username,quoteThis.author.displayAvatarURL({format: "png", size: 128, dynamic: true}),quoteThis.url) .setDescription(quoteThis.content) .setTimestamp(quoteThis.createdAt); if (author && author.displayColor) { @@ -132,19 +123,19 @@ module.exports = class embmaker extends commando.Command { } continue; } - if (value.toLowerCase().startsWith('remove')) { - const remove = value.slice('remove'.length).toLowerCase().trim().split(/ +/); - for(const remThis of remove) { - if (remThis === 'fields') { + if (value.startsWith("r ")) { + const r = value.slice("r ".length).toLowerCase().trim().split(/ +/); + for(const remThis of r) { + if (remThis === "f") { embed.fields = []; } - if (remThis === 'author') { + if (remThis === "a") { autName = null; autIcon = null; autUrl = null; embed.author = null; } - if (remThis === 'footer') { + if (remThis === "fo") { footertext = null; footericon = null; embed.footer = null; @@ -152,45 +143,40 @@ module.exports = class embmaker extends commando.Command { } continue; } - if (value.toLowerCase().startsWith('title')) { - const use = value.slice('title'.length).trim().replace(/\\(?!\\)/g,''); - embed.setTitle(isAdmin ? use : sentAdCheck(use)); + if (value.startsWith("t ")) { + const use = emoteMessage(this.client, value.slice("t ".length).trim().replace(/\\(?!\\)/g,"")); + embed.setTitle(isAdmin ? use : adCheck(use)); continue; } - if (value.toLowerCase().startsWith('desc')) { - const use = value.slice('desc'.length).trim().replace(/\\(?!\\)/g,''); - embed.setDescription(isAdmin ? use : sentAdCheck(use)); + if (value.startsWith("d ")) { + const use = emoteMessage(this.client, value.slice("d ".length).trim().replace(/\\(?!\\)/g,"")); + embed.setDescription(isAdmin ? use : adCheck(use)); continue; } - if (value.toLowerCase().startsWith('description')) { - const use = value.slice('description'.length).trim().replace(/\\(?!\\)/g,''); - embed.setDescription(isAdmin ? use : sentAdCheck(use)); - continue; - } - if (value.toLowerCase().startsWith("author")) { - const autData = value.trim().split(/( \-)+/); + if (value.startsWith("a ")) { + const autData = parseDash(value); for(const autVal of autData) { - if (autVal.toLowerCase().startsWith('name')) { - const use = autVal.slice('name'.length).trim().replace(/\\(?!\\)/g,''); - autName = isAdmin ? use : sentAdCheck(use); + if (autVal.startsWith("n ")) { + const use = autVal.slice("n ".length).trim().replace(/\\(?!\\)/g,""); + autName = isAdmin ? use : adCheck(use); continue; } - if (autVal.toLowerCase().startsWith('icon')) { - if (/^https?:\/\/\w+\.\w\w/.test(autVal.slice('icon'.length).trim())) { - autIcon = autVal.slice('icon'.length).trim(); + if (autVal.startsWith("i ")) { + if (reValidURL.test(autVal.slice("i ".length).trim())) { + autIcon = autVal.slice("i ".length).trim(); } else { reportMessage += "**[AUTHOR]** Invalid icon URL.\n"; autIcon = null; } continue; } - if (autVal.toLowerCase().startsWith('url')) { + if (autVal.startsWith("u ")) { if (!isAdmin) { reportMessage += "**[AUTHOR]** URL requires Administrator.\n"; continue; } - if (/^https?:\/\/\w+\.\w\w/.test(autVal.slice('url'.length).trim())) { - autUrl = autVal.slice('url'.length).trim(); + if (reValidURL.test(autVal.slice("u ".length).trim())) { + autUrl = autVal.slice("u ".length).trim(); } else { reportMessage += "**[AUTHOR]** Invalid URL.\n"; autUrl = null; @@ -200,56 +186,56 @@ module.exports = class embmaker extends commando.Command { } continue; } - if (value.toLowerCase().startsWith("color")) { - const colorName = value.slice("color".length).trim(); + if (value.startsWith("c ")) { + const colorName = value.slice("c ".length).trim(); const color = getColor(colorName); if (color) { embed.setColor(color); } continue; } - if (value.toLowerCase().startsWith("image")) { - if (/^https?:\/\/\w+\.\w\w/.test(value.slice("image".length).trim())) { - embed.setImage(value.slice("image".length).trim()); + if (value.startsWith("i ")) { + if (reValidURL.test(value.slice("i ".length).trim())) { + embed.setImage(value.slice("i ".length).trim()); } else { reportMessage += "**[IMAGE]** Invalid URL.\n"; embed.setImage(null); } continue; } - if (value.toLowerCase().startsWith("thumbnail")) { - if (/^https?:\/\/\w+\.\w\w/.test(value.slice("thumbnail".length).trim())) { - embed.setThumbnail(value.slice("thumbnail".length).trim()); + if (value.startsWith("th ")) { + if (reValidURL.test(value.slice("th ".length).trim())) { + embed.setThumbnail(value.slice("th ".length).trim()); } else { reportMessage += "**[THUMBNAIL]** Invalid URL.\n"; embed.setThumbnail(null); } continue; } - if (value.toLowerCase().startsWith('url')) { + if (value.startsWith("u ")) { if (!isAdmin) { reportMessage += "**[URL]** Requires Administrator.\n"; continue; } - if (/^https?:\/\/\w+\.\w\w/.test(value.slice("url".length).trim())) { - embed.setURL(value.slice("url".length).trim()); + if (reValidURL.test(value.slice("u ".length).trim())) { + embed.setURL(value.slice("u ".length).trim()); } else { reportMessage += "**[URL]** Invalid URL.\n"; embed.setURL(null); } continue; } - if (value.toLowerCase().startsWith('attachment')) { - const attach = value.slice("attachments".length).trim().split(/ +/); + if (value.startsWith("at ")) { + const attach = value.slice("at ".length).trim().split(/ +/); for(const theFile of attach) { - if (/^https?:\/\/\w+\.\w\w/.test(theFile)) { + if (reValidURL.test(theFile)) { newAttach.push(theFile); } else { - if (theFile.toLowerCase() !== "-copy") { + if (theFile !== "-c") { reportMessage += "**[ATTACHMENT]** Invalid URL.\n"; } } - if (theFile.toLowerCase() === '-copy' && editSrc) { + if (theFile === "-c" && editSrc) { if (editSrc.attachments[0].length > 0) { for(const attach of editSrc.attachments) { attach.map(g => { @@ -263,12 +249,12 @@ module.exports = class embmaker extends commando.Command { } continue; } - if (value.toLowerCase().startsWith("timestamp")) { - const use = value.slice("timestamp".length).trim(); + if (value.startsWith("ti ")) { + const use = value.slice("ti ".length).trim(); if(!/\D/.test(use)) { embed.setTimestamp(parseInt(use, 10)); } else { - if (use.toLowerCase() === 'now') { + if (use === "now") { embed.setTimestamp(msg.createdAt); } else { embed.setTimestamp(use); @@ -283,16 +269,16 @@ module.exports = class embmaker extends commando.Command { } continue; } - if (value.toLowerCase().startsWith('footer')) { - const footerData = value.trim().split(/( \-)+/); + if (value.startsWith("fo ")) { + const footerData = parseDash(value); for(const footval of footerData) { - if (footval.toLowerCase().startsWith('text')) { - const use = footval.slice("text".length).trim().replace(/\\(?!\\)/g,''); - footertext = isAdmin ? use : sentAdCheck(use); + if (footval.startsWith("t ")) { + const use = emoteMessage(this.client, footval.slice("t ".length).trim().replace(/\\(?!\\)/g,"")); + footertext = isAdmin ? use : adCheck(use); } - if (footval.toLowerCase().startsWith('icon')) { - if (/^https?:\/\/\w+\.\w\w/.test(footval.slice('icon'.length).trim())) { - footericon = footval.slice('icon'.length).trim(); + if (footval.startsWith("i ")) { + if (reValidURL.test(footval.slice("i ".length).trim())) { + footericon = footval.slice("i ".length).trim(); } else { reportMessage += "**[FOOTER]** Invalid icon URL.\n"; footericon = null; @@ -301,46 +287,42 @@ module.exports = class embmaker extends commando.Command { } continue; } - if (value.toLowerCase().startsWith('newfield')) { - const fieldData = value.trim().split(/( \-)+/); + if (value.startsWith("f ")) { + const fieldData = parseDash(value); let fieldName,fieldValue, inline = false; for(const data of fieldData) { - if (data.toLowerCase().startsWith('name')) { - const use = data.slice('name'.length).trim().replace(/\\(?!\\)/g,''); - fieldName = isAdmin ? use : sentAdCheck(use); + if (data.startsWith("n ")) { + const use = emoteMessage(this.client, data.slice("n ".length).trim().replace(/\\(?!\\)/g,"")); + fieldName = isAdmin ? use : adCheck(use); } - if (data.toLowerCase().startsWith('desc')) { - const use = data.slice('desc'.length).trim().replace(/\\(?!\\)/g,''); - fieldValue = isAdmin ? use : sentAdCheck(use); + if (data.startsWith("d ")) { + const use = emoteMessage(this.client, data.slice("d ".length).trim().replace(/\\(?!\\)/g,"")); + fieldValue = isAdmin ? use : adCheck(use); } - if (data.toLowerCase().startsWith('description')) { - const use = data.slice('description'.length).trim().replace(/\\(?!\\)/g,''); - fieldValue = isAdmin ? use : sentAdCheck(use); - } - if (data.toLowerCase().startsWith('inline')) { + if (data[0] === "i") { inline = true; } } if (!fieldName) { - fieldName = '​'; + fieldName = "​"; } if (!fieldValue) { - fieldValue = '_ _'; + fieldValue = "_ _"; } embed.addField(fieldName, fieldValue, inline); continue; } - if (value.toLowerCase().startsWith('content')) { - const use = value.slice('content'.length).trim().replace(/\\(?!\\)/g,''); - content = isAdmin ? use : sentAdCheck(use); + if (value.startsWith("co ")) { + const use = emoteMessage(this.client, value.slice("co ".length).trim().replace(/\\(?!\\)/g,"")); + content = isAdmin ? use : adCheck(use); continue; } - if (value.toLowerCase().startsWith('channel')) { - let ID = cleanMentionID(value.slice('channel'.length).trim()); - if (ID.toLowerCase() === 'here') { + if (value.startsWith("ch ")) { + let ID = cleanMentionID(value.slice("ch ".length).trim()); + if (ID === "here") { channel = msg.channel; } else { - channel = getChannelProchedure(msg, ID) + channel = getChannel(msg, ID, ["category", "voice"]) if (!channel) { reportMessage += "**[CHANNEL]** Unknown channel.\n"; } else { @@ -357,37 +339,22 @@ module.exports = class embmaker extends commando.Command { continue; } } - if(autIcon === false) { - if (embed.author.name) { - delete embed.author.name; + if(autIcon === false && embed.author.name) delete embed.author.name; + if (!autName && autIcon) autName = "​"; + if (autName || autIcon && embed.author !== null) embed.setAuthor(autName, autIcon, autUrl); + if (!footertext && footericon) footertext = "​"; + if (footertext || footericon && embed.footer !== null) embed.setFooter(footertext, footericon); + if (embed.length === 0 && (embed.thumbnail === null || embed.thumbnail.url === null) && embed.author === null && (embed.image === null || embed.image.url === null) && !footericon) { + if (embed.timestamp) embed.setFooter("​"); else { + embed = defaultImageEmbed(msg, null, "Usage"); + embed.setDescription(this.details); } } - if (!autName && autIcon) { - autName = '​'; - } - if (autName || autIcon && embed.author !== null) { - embed.setAuthor(autName,autIcon,autUrl); - } - if (footertext || footericon && embed.footer !== null) { - embed.setFooter(footertext,footericon); - } - if (embed.length === 0 && (embed.thumbnail === null || embed.thumbnail.url === null) && embed.author === null && (embed.image === null || embed.image.url === null)) { - if (embed.timestamp) { - embed.setFooter('​'); - } else { - embed.setDescription("_ _"); - } - } - if (embed.color === 16777215) { - embed.setColor(16777214); - } - if (embed.description === '​' && (content || newAttach.length > 0)) { - embed = null; - } + if (embed.color === 16777215) embed.setColor(16777214); + if (embed.description === "​" && (content || newAttach.length > 0)) embed = null; let sent = []; - if (reportMessage.length > 0) { - sent.push(trySend(this.client, msg, reportMessage, !isAdmin)); - } + if (editSrc && editSrc.author != this.client.user && !channel) reportMessage += "I can\"t edit that, so here <:catstareLife:794930503076675584>\n"; + if (reportMessage.length > 0) sent.push(trySend(this.client, msg, reportMessage, !isAdmin)); if (editSrc) { if (channel) { if (msg.guild && !this.client.owners.includes(msg.author)) { @@ -415,11 +382,10 @@ module.exports = class embmaker extends commando.Command { if (editSrc.author === this.client.user) { sent.push(editSrc.edit({content:content,embed:embed,files:newAttach}).catch(e => { errLog(e, msg, this.client); - sent.push(trySend(this.client, msg, 'Something\'s wrong, i can\'t edit that so here <:WhenLife:773061840351657984>')); + sent.push(trySend(this.client, msg, "Something\"s wrong, i can\"t edit that so here <:WhenLife:773061840351657984>")); sent.push(trySend(this.client, msg, {content:content,embed:embed,files:newAttach})); })); } else { - sent.push(trySend(this.client, msg, 'I can\'t edit that, so here <:catstareLife:794930503076675584>')); sent.push(trySend(this.client, msg, {content:content,embed:embed,files:newAttach})); } } @@ -438,10 +404,10 @@ module.exports = class embmaker extends commando.Command { } if (await sent[0]) { tryReact(msg, "a:yesLife:794788847996370945"); + ranLog(msg, ("```js\n" + JSON.stringify(embed, (k, v) => v ?? undefined, 2) + "```")); } else { - return noPerm(msg); + noPerm(msg); } - ranLog(msg, ("```js\n" + JSON.stringify(embed, (k, v) => v ?? undefined, 2) + "```")); return sent; } catch (e) { return errLog(e, msg, this.client, true, "", true); diff --git a/cmds/utility/lookup.js b/cmds/utility/lookup.js index 47798de..844cc30 100644 --- a/cmds/utility/lookup.js +++ b/cmds/utility/lookup.js @@ -9,14 +9,18 @@ module.exports = class lookup extends commando.Command { name: "lookup", memberName: "lookup", group: "utility", - description: "Lookup something in the server using mention, ID, or RegExp." + description: "Lookup something in the server using mention, ID, or RegExp.", + guildOnly: true }); } async run(msg, arg) { + if (!arg) { + return trySend(this.client, msg, "Args: `--[m|c|r]` [Member|Channel|Role]: `[mention|ID|name]` `--s` Show: `[number]`") + } let show; - const showArg = arg.match(/(? 0) { const res = parseInt(val, 10); @@ -24,13 +28,13 @@ module.exports = class lookup extends commando.Command { } } } - arg = arg.replace(/(? 0) { - return trySend(this.client, msg, { content: memMes, split: { char: ",", append: ",```", prepend: "```js", maxLength: 4000 } }); + return trySend(this.client, msg, { content: memMes, split: { char: ",", append: ",```", prepend: "```js", maxLength: 2000 } }); } } }; \ No newline at end of file diff --git a/cmds/utility/mesemb.js b/cmds/utility/mesemb.js index fd46ba8..024675b 100644 --- a/cmds/utility/mesemb.js +++ b/cmds/utility/mesemb.js @@ -18,7 +18,7 @@ module.exports = class mesemb extends commando.Command { if (!message) { return trySend(this.client, msg, "404 message not found!"); } - const mesemb = '```js\n' + JSON.stringify(message.embeds, (k, v) => v ?? undefined, 2).replace(/`/g,"\\`") + '```'; - return trySend(this.client, msg, { content: 'Collected:' + mesemb, split: { maxLength: 4000, char: ",", append: ',```', prepend:'```js\n' }}); + const mesemb = '```js\n' + JSON.stringify(message.embeds, (k, v) => v ?? undefined, 2).replace(/```/g,"`\\``") + '```'; + return trySend(this.client, msg, { content: 'Collected:' + mesemb, split: { maxLength: 2000, char: ",", append: ',```', prepend:'```js\n' }}); } }; \ No newline at end of file diff --git a/cmds/utility/mesinfo.js b/cmds/utility/mesinfo.js index 6189507..63ec150 100644 --- a/cmds/utility/mesinfo.js +++ b/cmds/utility/mesinfo.js @@ -18,11 +18,11 @@ module.exports = class mesinfo extends commando.Command { if (!message) { return trySend(this.client, msg, "No message with that ID <:catstareLife:794930503076675584>") } - const mesinfo = 'Collected:```js\n'+JSON.stringify(message, (k, v) => v ?? undefined, 2).replace(/`/g,"\\`")+'```'; + const mesinfo = 'Collected:```js\n'+JSON.stringify(message, (k, v) => v ?? undefined, 2).replace(/```/g,"`\\``")+'```'; const mentionJSON = message.mentions.toJSON(); const sendMentionInfo = 'Mentions:```js\n'+JSON.stringify(mentionJSON, (k, v) => v ?? undefined, 2)+'```'; const Attachments = 'Attachments:```js\n'+JSON.stringify(message.attachments, (k, v) => v ?? undefined, 2)+'```'; const sendmesinfo = mesinfo+sendMentionInfo+Attachments; - return trySend(this.client, msg, {content:sendmesinfo,split:{ maxLength: 4000, char: ",",append: ',```', prepend: '```js\n' }}); + return trySend(this.client, msg, {content:sendmesinfo,split:{ maxLength: 2000, char: ",",append: ',```', prepend: '```js\n' }}); } }; \ No newline at end of file diff --git a/cmds/utility/perms.js b/cmds/utility/perms.js index a726efc..c2ae9ba 100644 --- a/cmds/utility/perms.js +++ b/cmds/utility/perms.js @@ -1 +1,87 @@ -'use strict'; \ No newline at end of file +'use strict'; + +const commando = require("@iceprod/discord.js-commando"), +{ getMember, trySend, defaultImageEmbed, getChannel } = require("../../resources/functions"); +const { Message, GuildChannel } = require("discord.js"); +const getColor = require("../../resources/getColor"); + +module.exports = class perms extends commando.Command { + constructor(client) { + super(client, { + name: "perms", + memberName: "perms", + aliases: ["perm", "permissions", "permission"], + group: "utility", + description: "description", + guildOnly: true + }); + } + /** + * + * @param {Message} msg + * @param {String} arg + * @returns + */ + run(msg, arg) { + let member, channel, mes = ""; + if (arg) { + const forC = arg.match(/(? 0) { + member = getMember(msg.guild, find)?.[0]; + } else { + member = msg.member; + } + } else { + member = msg.member; + mes += `Args:\n\`user_[mention|ID|name]\` \`--c\` \`[channel_[name|ID]|here]\`\n`; + } + if (!member) { + return trySend(this.client, msg, "Is that your gf?"); + } + const perms = member.permissions.serialize(); + let res = [], chanres = []; + for (const key in perms) { + const element = perms[key]; + if (element) { + res.push(key); + } + } + if (channel) { + const res = channel.permissionsFor(member).serialize(); + for (const key in res) { + const el = res[key]; + if (el) { + chanres.push(key); + } + } + } + const title = `Permissions for: \`${member.user.tag}\``; + mes += `**Default:**\`\`\`js\n`; + if (res.length > 0) { + mes += `${res.join(", ")}\`\`\``; + } else { + mes += `NONE LMFAOO\`\`\``; + } + const emb = defaultImageEmbed(msg, null, title); + if (chanres.length > 0) { + emb.addField(`In channel: \`${channel.name}\``, `\`\`\`js\n${chanres.join(", ")}\`\`\``); + } + emb.setDescription(mes) + .setColor(getColor(member.displayColor)) + .setThumbnail(member.user.displayAvatarURL({size: 4096, format: "png", dynamic: true})); + return trySend(this.client, msg, emb); + } +}; \ No newline at end of file diff --git a/cmds/utility/quoteotd.js b/cmds/utility/quoteotd.js index 94d616e..8cc9840 100644 --- a/cmds/utility/quoteotd.js +++ b/cmds/utility/quoteotd.js @@ -1,7 +1,7 @@ 'use strict'; const commando = require("@iceprod/discord.js-commando"); -const { trySend, ranLog } = require("../../resources/functions"); +const { trySend, ranLog, parseDoubleDash } = require("../../resources/functions"); const { database } = require("../../database/mongo"); const col = database.collection("Guild"); @@ -18,7 +18,7 @@ module.exports = class quoteotd extends commando.Command { }); } async run(msg, arg) { - const args = arg.trim().split(/(\-\-)+/); + const args = parseDoubleDash(arg); if (args.length < 2) { return trySend(this.client, msg, `Provide argument: \`--channel [mention, ID], --text [footer text], --icon [url footer icon]\``); } diff --git a/cmds/utility/uinfo.js b/cmds/utility/uinfo.js index 728cbd8..b1693af 100644 --- a/cmds/utility/uinfo.js +++ b/cmds/utility/uinfo.js @@ -39,7 +39,7 @@ module.exports = class uinfo extends commando.Command { result += 'Display color:```js\n'+member.displayColor+'```'; } } - return trySend(this.client, msg, { content: result, split:{ maxLength: 4000, char: ",", append: ',```', prepend: '```js\n' }}); + return trySend(this.client, msg, { content: result, split:{ maxLength: 2000, char: ",", append: ',```', prepend: '```js\n' }}); } catch (e) { return trySend(this.client, msg, "404 ERROR not found~"); } diff --git a/database/mongo.js b/database/mongo.js index a0d97fe..9935cea 100644 --- a/database/mongo.js +++ b/database/mongo.js @@ -1,22 +1,18 @@ 'use strict'; const { mongoServer } = require("../config.json"); -const { MongoClient } = require("mongodb"); -const dbClient = new MongoClient(mongoServer,{ +const { MongoClient, Db } = require("mongodb"); +const dbClient = new MongoClient(mongoServer, { useUnifiedTopology: true }); dbClient.connect(e => { if (e) { - console.error(e); - return process.exit(); + return console.error(e); } console.log("Database connected!"); }); const database = dbClient.db("Shasha"); -/** - * @type {dbClient: MongoClient, database: Db} - */ module.exports = { dbClient, database } \ No newline at end of file diff --git a/package.json b/package.json index e5262a9..f9c8bd5 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,11 @@ "erlpack": "github:discord/erlpack", "fs-extra": "^9.1.0", "lodash": "^4.17.21", + "moment": "^2.29.1", "mongodb": "^3.6.6", + "nekos-best.js": "^2.0.2", "node": "^15.12.0", + "require-all": "^3.0.0", "sqlite": "^4.0.21", "sqlite3": "^5.0.2", "utf-8-validate": "^5.0.4", diff --git a/resources/emoteMessage.js b/resources/emoteMessage.js index 2c761c4..ecec1c8 100644 --- a/resources/emoteMessage.js +++ b/resources/emoteMessage.js @@ -1,26 +1,18 @@ 'use strict'; module.exports = function emoteMessage(client, content) { - const emotes = content.match(/:\w{1,32}:(?!\d{17,19}>)/g); - if (emotes?.length > 0) { - let theEmotes = []; - for (const emoteName of emotes) { - let findThis = emoteName.slice(1, -1); - const findEmote = client.emojis.cache.array(); - let found; - for (const emote of findEmote) { - if (emote.name.toLowerCase() === findThis.toLowerCase()) { - found = emote; - break; - } - } - theEmotes.push(found); - } - if (theEmotes.length > 0) { - for (let index = 0; index < emotes.length; index++) { - if (theEmotes[index]) { - content = content.replace(emotes[index], `<${theEmotes[index].animated ? "a" : ""}:${theEmotes[index].name}:${theEmotes[index].id}>`); - } + const E = content?.match(/:\w{1,32}:(?!\d{17,19}>)/g); + if (!E || E.length === 0) return content; + let tE = []; + for (const eN of E) { + let findThis = eN.slice(1, -1); + let found = client.emojis.cache.map(r => r).filter(r => r.name.toLowerCase() === findThis.toLowerCase())?.[0]; + tE.push(found); + } + if (tE.length > 0) { + for (let index = 0; index < E.length; index++) { + if (tE[index]) { + content = content.replace(E[index], `<${tE[index].animated ? "a" : ""}:${tE[index].name}:${tE[index].id}>`); } } } diff --git a/resources/eventsLogger/guildMemberAdd.js b/resources/eventsLogger/guildMemberAdd.js index 863e79d..05fa8d8 100644 --- a/resources/eventsLogger/guildMemberAdd.js +++ b/resources/eventsLogger/guildMemberAdd.js @@ -1,7 +1,7 @@ 'use strict'; const { GuildMember } = require("discord.js"); -const { getChannelProchedure, defaultEventLogEmbed, trySend } = require("../functions"); +const { getChannel, defaultEventLogEmbed, trySend } = require("../functions"); const getColor = require("../getColor"); /** @@ -10,15 +10,15 @@ const getColor = require("../getColor"); * @returns */ module.exports = (member) => { - if (member.guild.eventChannels?.joinLeave) { - const log = getChannelProchedure(member, member.guild.eventChannels.joinLeave); + if (member.guild.eventChannels?.join) { + const log = getChannel(member, member.guild.eventChannels.join); if (!log) return; const emb = defaultEventLogEmbed(member.guild); emb .setTitle("User `" + member.user.tag + "` joined") .setThumbnail(member.user.displayAvatarURL({format: "png", size: 4096, dynamic: true})) .setColor(getColor("cyan")) - .addField("Registered", "**" + new Date(member.user.createdAt).toUTCString().slice(0, -4) + "**", true) + .addField("Registered", "**" + member.user.createdAt.toUTCString().slice(0, -4) + "**", true) .setDescription(`<@!${member.id}> (${member.id}) just joined.\nWe have ${member.guild.memberCount} total members now.`); return trySend(member.client, log, emb); } diff --git a/resources/eventsLogger/guildMemberRemove.js b/resources/eventsLogger/guildMemberRemove.js index 11ba860..ad8785c 100644 --- a/resources/eventsLogger/guildMemberRemove.js +++ b/resources/eventsLogger/guildMemberRemove.js @@ -1,7 +1,7 @@ 'use strict'; const { GuildMember } = require("discord.js"); -const { getChannelProchedure, defaultEventLogEmbed, trySend } = require("../functions"); +const { getChannel, defaultEventLogEmbed, trySend } = require("../functions"); const getColor = require("../getColor"); /** @@ -10,8 +10,8 @@ const getColor = require("../getColor"); * @returns */ module.exports = (member) => { - if (member.guild.eventChannels?.joinLeave) { - const log = getChannelProchedure(member, member.guild.eventChannels.joinLeave); + if (member.guild.eventChannels?.leave) { + const log = getChannel(member, member.guild.eventChannels.leave); if (!log) return; const days = Math.floor(new Date(new Date().valueOf() + member.client.matchTimestamp - member.joinedAt.valueOf()).valueOf() / 86400000), emb = defaultEventLogEmbed(member.guild); @@ -19,8 +19,8 @@ module.exports = (member) => { .setTitle("Member `" + member.user.tag + "` left") .setThumbnail(member.user.displayAvatarURL({format: "png", size: 4096, dynamic: true})) .setColor(getColor("yellow")) - .addField("Registered", "**" + new Date(member.user.createdAt).toUTCString().slice(0, -4) + "**", true) - .addField("Joined", "**" + new Date(member.joinedAt).toUTCString().slice(0, -4) + "**" + `\n(${days > 0 ? `${days} day${days > 1 ? "s" : ""} ago` : "Today"})`, true) + .addField("Registered", "**" + member.user.createdAt.toUTCString().slice(0, -4) + "**", true) + .addField("Joined", "**" + member.joinedAt.toUTCString().slice(0, -4) + "**" + `\n(${days > 0 ? `${days} day${days > 1 ? "s" : ""} ago` : "Today"})`, true) .addField("Roles", member.roles.cache.size > 1 ? "<@&" + member.roles.cache.sort((a, b) => b.position - a.position).map(r => r.id).slice(0, -1).join(">, <@&") + ">" : "`[NONE]") .setDescription(`<@!${member.id}> (${member.id}) just left.\nWe have ${member.guild.memberCount} total members now.`); return trySend(member.client, log, emb); diff --git a/resources/eventsLogger/guildMemberUpdate.js b/resources/eventsLogger/guildMemberUpdate.js index e01a154..39e8143 100644 --- a/resources/eventsLogger/guildMemberUpdate.js +++ b/resources/eventsLogger/guildMemberUpdate.js @@ -1,7 +1,7 @@ 'use strict'; const { GuildMember } = require("discord.js"); -const { defaultEventLogEmbed, getChannelProchedure, trySend } = require("../functions"); +const { defaultEventLogEmbed, getChannel, trySend } = require("../functions"); const getColor = require("../getColor"); /** @@ -11,7 +11,7 @@ const getColor = require("../getColor"); * @returns */ module.exports = (memberold, membernew) => { - if (membernew.guild.eventChannels?.memberRole === undefined && membernew.guild.eventChannels?.member === undefined) { + if (!membernew.guild.eventChannels?.memberRole && !membernew.guild.eventChannels?.member) { if (membernew.user.cachedAvatarURL != membernew.user.displayAvatarURL({format: "png", size: 4096, dynamic: true})) { membernew.user.cachedAvatarURL = membernew.user.displayAvatarURL({format: "png", size: 4096, dynamic: true}); }; @@ -23,18 +23,18 @@ module.exports = (memberold, membernew) => { .setThumbnail(membernew.user.cachedAvatarURL ?? memberold.toJSON().displayAvatarURL) .setColor(getColor("blue")); if (membernew.guild.eventChannels?.memberRole) { - log = getChannelProchedure(membernew, membernew.guild.eventChannels.memberRole); + log = getChannel(membernew, membernew.guild.eventChannels.memberRole); if (membernew.roles.cache.size > memberold.roles.cache.size) { - emb.addField("Role added", "<@&" + membernew.roles.cache.difference(memberold.roles.cache).sort((a, b) => b.position - a.position).map(r => r.id).join(">, <@&") + ">") - .addField("Old roles", memberold.roles.cache.size > 1 ? "<@&" + memberold.roles.cache.sort((a, b) => b.position - a.position).map(r => r.id).slice(0, -1).join(">, <@&") + ">" : "`[NONE]"); + emb.addField("Role added", ("<@&" + membernew.roles.cache.difference(memberold.roles.cache).sort((a, b) => b.position - a.position).map(r => r.id).join(">, <@&") + ">").slice(0, 2048)) + .setDescription("**Old roles**\n" + (memberold.roles.cache.size > 1 ? "<@&" + memberold.roles.cache.sort((a, b) => b.position - a.position).map(r => r.id).slice(0, -1).join(">, <@&") + ">" : "`[NONE]`")); } if (membernew.roles.cache.size < memberold.roles.cache.size) { - emb.addField("Role removed", "<@&" + memberold.roles.cache.difference(membernew.roles.cache).sort((a, b) => b.position - a.position).map(r => r.id).join(">, <@&") + ">") - .addField("Current roles", membernew.roles.cache.size > 1 ? "<@&" + membernew.roles.cache.sort((a, b) => b.position - a.position).map(r => r.id).slice(0, -1).join(">, <@&") + ">" : "`[NONE]"); + emb.addField("Role removed", ("<@&" + memberold.roles.cache.difference(membernew.roles.cache).sort((a, b) => b.position - a.position).map(r => r.id).join(">, <@&") + ">").slice(0, 2048)) + .setDescription("**Current roles**\n" + (membernew.roles.cache.size > 1 ? "<@&" + membernew.roles.cache.sort((a, b) => b.position - a.position).map(r => r.id).slice(0, -1).join(">, <@&") + ">" : "`[NONE]`")); } } if (membernew.guild.eventChannels?.member && membernew.roles.cache.size === memberold.roles.cache.size) { - log = getChannelProchedure(membernew, membernew.guild.eventChannels.member); + log = getChannel(membernew, membernew.guild.eventChannels.member); if (membernew.displayName != memberold.displayName) { emb.addField("Nickname", "Changed from `" + memberold.displayName + "` to `" + membernew.displayName + "`"); } @@ -47,5 +47,6 @@ module.exports = (memberold, membernew) => { if (membernew.user.cachedAvatarURL != membernew.user.displayAvatarURL({format: "png", size: 4096, dynamic: true})) { membernew.user.cachedAvatarURL = membernew.user.displayAvatarURL({format: "png", size: 4096, dynamic: true}); }; + if (!emb.fields || emb.fields.length === 0) return; return trySend(membernew.client, log, emb); } diff --git a/resources/eventsLogger/message.js b/resources/eventsLogger/message.js index 2217ed4..105be97 100644 --- a/resources/eventsLogger/message.js +++ b/resources/eventsLogger/message.js @@ -25,9 +25,9 @@ async function letsChat(msg) { if (msg.channel.id === configFile.chatChannel && !msg.author.bot && !msg.isCommand && msg.cleanContent.length > 0) { return msg.channel.startTyping().then(trySend(msg.client, msg, await chatAnswer(msg.cleanContent)) ).then(r => { - msg.channel.stopTyping(); return r; - }).catch(msg.channel.stopTyping()); + }).catch(() => {}) + .finally(msg.channel.stopTyping()); } } diff --git a/resources/eventsLogger/messageDelete.js b/resources/eventsLogger/messageDelete.js index 972c01f..06bfbe9 100644 --- a/resources/eventsLogger/messageDelete.js +++ b/resources/eventsLogger/messageDelete.js @@ -1,7 +1,7 @@ 'use strict'; const { Message } = require("discord.js"); -const { trySend, defaultEventLogEmbed, getChannelProchedure, splitOnLength } = require("../functions"); +const { trySend, defaultEventLogEmbed, getChannel, splitOnLength } = require("../functions"); const getColor = require("../getColor"); /** @@ -11,27 +11,27 @@ const getColor = require("../getColor"); */ module.exports = async (msg) => { if (msg.partial) return; - const ignored = msg.guild.eventChannels.message.ignore?.includes(msg.channel.id) ?? false; + const ignored = msg.guild.eventChannels.mesDel.ignore?.includes(msg.channel.id) ?? false; let check = false; - if (msg.channel.id === msg.guild.eventChannels?.message?.channel && msg.author ? msg.author !== msg.client.user : false && ignored === false) check = true; - if (msg.guild.eventChannels?.message?.channel !== msg.channel.id && ignored === false || check) { - const log = getChannelProchedure(msg, msg.guild.eventChannels.message.channel); + if (msg.channel.id === msg.guild.eventChannels?.mesDel?.channel && msg.author ? msg.author !== msg.client.user : false && ignored === false) check = true; + if (msg.guild.eventChannels?.mesDel?.channel !== msg.channel.id && ignored === false || check) { + const log = getChannel(msg, msg.guild.eventChannels.mesDel.channel); if (!log || !msg.author) return; const emb = defaultEventLogEmbed(msg.guild); emb.setColor(getColor("yellow")) - .setTitle("Message " + msg.id + " deleted") + .setTitle((!msg.webhookID ? "Message " + msg.id : "Webhook " + msg.webhookID) + " deleted") .setDescription(msg.content.length > 0 ? msg.content : "`[EMPTY]`") - .setAuthor(emb.author.name, msg.author?.displayAvatarURL({format: "png", size: 4096, dynamic: true})) + .setAuthor(emb.author.name, msg.author?.displayAvatarURL({format: "png", size: 128, dynamic: true})) .addField("Author", `<@!${msg.author?.id}>\n\`${msg.author?.tag}\`\n(${msg.author?.id})`,true) .addField("Channel", `<#${msg.channel?.id}>\n\`${msg.channel?.name}\`\n(${msg.channel?.id})`,true) .setURL(msg.url); - if (msg.attachments?.array().length > 0) { - let arr = msg.attachments.array().map(r => r.proxyURL); + if (msg.attachments?.size > 0) { + let arr = msg.attachments.map(r => r.proxyURL); const toField = splitOnLength(arr, 1024); for (const add of toField) emb.addField(emb.fields.length === 2 ? "Attachment" : "​", add.join("\n")); } if (msg.embeds?.[0]) { - const arr = JSON.stringify(msg.embeds[0], (k, v) => v ?? undefined, 2).replace(/`/g,"\\`").split(","); + const arr = JSON.stringify(msg.embeds[0], (k, v) => v ?? undefined, 2).replace(/```/g,"`\\``").split(","); const toField = splitOnLength(arr, 1010, ",\n"); for (let i = 0; i < toField.length; i++) emb.addField(i === 0 ? "Embed" : "​", "```js\n" + toField[i].join(",") + ((i !== toField.length - 1) ? "," : "") + "```"); } diff --git a/resources/eventsLogger/messageUpdate.js b/resources/eventsLogger/messageUpdate.js index 7192da8..98d2348 100644 --- a/resources/eventsLogger/messageUpdate.js +++ b/resources/eventsLogger/messageUpdate.js @@ -1,7 +1,7 @@ 'use strict'; const { Message } = require("discord.js"); -const { trySend, defaultEventLogEmbed, getChannelProchedure } = require("../functions"); +const { trySend, defaultEventLogEmbed, getChannel } = require("../functions"); const getColor = require("../getColor"); /** @@ -14,11 +14,11 @@ module.exports = async (msgold, msgnew) => { if (msgnew.partial) msgnew = await msgnew.fetch(); if (msgnew.partial) return; if (msgnew.content === msgold.content) return; - const ignored = msgnew.guild.eventChannels.message.ignore?.includes(msgnew.channel.id) ?? false; + const ignored = msgnew.guild.eventChannels.mesEd.ignore?.includes(msgnew.channel.id) ?? false; let check = false; - if (msgnew.channel.id === msgnew.guild.eventChannels?.message?.channel && msgnew.author ? msgnew.author !== msgnew.client.user : false && ignored === false) check = true; - if (msgnew.guild.eventChannels?.message?.channel !== msgnew.channel.id && ignored === false || check) { - const log = getChannelProchedure(msgnew, msgnew.guild.eventChannels.message.channel); + if (msgnew.channel.id === msgnew.guild.eventChannels?.mesEd?.channel && msgnew.author ? msgnew.author !== msgnew.client.user : false && ignored === false) check = true; + if (msgnew.guild.eventChannels?.mesEd?.channel !== msgnew.channel.id && ignored === false || check) { + const log = getChannel(msgnew, msgnew.guild.eventChannels.mesEd.channel); if (!log || !msgnew.author) return; const emb = defaultEventLogEmbed(msgnew.guild); emb @@ -26,7 +26,7 @@ module.exports = async (msgold, msgnew) => { .setDescription(msgnew.content.length > 0 ? msgnew.content : "`[EMPTY]`") .addField("Original content", msgold.content?.length > 0 ? (msgold.content.slice(0, msgold.content.length < 1025 ? 1024 : 1021) + (msgold.content.length < 1025 ? "" : "...")) : "`[EMPTY]`" ) .setTitle("Message " + msgnew.id + " edited") - .setAuthor(emb.author.name, msgnew.author.displayAvatarURL({format: "png", size: 4096, dynamic: true})) + .setAuthor(emb.author.name, msgnew.author.displayAvatarURL({format: "png", size: 128, dynamic: true})) .addField("Author", `<@!${msgnew.author?.id}>\n\`${msgnew.author?.tag}\`\n(${msgnew.author?.id})`,true) .addField("Channel", `<#${msgnew.channel?.id}>\n\`${msgnew.channel?.name}\`\n(${msgnew.channel?.id})`,true) .setURL(msgnew.url); diff --git a/resources/functions.js b/resources/functions.js index 582e48a..eb6ce79 100644 --- a/resources/functions.js +++ b/resources/functions.js @@ -1,8 +1,7 @@ 'use strict'; -const { MessageEmbed, Message, GuildMember, User, Client, GuildChannel, Role, MessageOptions, TextChannel, DMChannel, Guild, Channel } = require('discord.js'); +const { MessageEmbed, Message, GuildMember, User, GuildChannel, Role, MessageOptions, TextChannel, DMChannel, Guild, Channel } = require('discord.js'); const { defaultErrorLogChannel, ranLogger } = require("../config.json"); -const { database } = require("../database/mongo"); const { timestampAt } = require('./debug'); const getColor = require('./getColor'); const { randomColors } = require("../config.json"); @@ -12,76 +11,72 @@ const { CommandoMessage, CommandoClient } = require('@iceprod/discord.js-command * Log an error. Second or third argument is required * @param {Error} theError - Catched error (error) * @param {CommandoMessage} msg - Message object (msg) - * @param {Client} client - This client (this.client) + * @param {CommandoClient} client - This client (this.client) * @param {Boolean} sendTheError - Add error content to notify message (true | false) * @param {String} errorMessage - Error message ("You don't have enough permission to use that command!") * @param {Boolean} notify - Send error to user who ran the command */ async function errLog(theError, msg, client, sendTheError, errorMessage, notify) { - if (!(theError instanceof Error) || !(msg ?? client)) return console.error("[ERRLOG] Not error instance or no required param.\n", theError); - let [logThis, inLogChannel, sendErr] = ['', '', '']; - if (msg) { + if (!client && msg) client = msg.client; + if (!(theError instanceof Error) || !client) return console.error("[ERRLOG] Not error instance or no required param:", theError); + let [ret, logThis, inLogChannel, sendErr] = [null, '', '', '']; + if (msg instanceof Message) { + client.emit("commandError", msg.command, theError, msg); logThis = `\`${msg.command?.name}\` (${msg.id}) ${msg.url} in ${msg.guild ? `**${msg.channel.name}** (${msg.channel.id}) of **${msg.guild.name}** (${msg.guild.id})` : `**DM**`} ran by **${msg.author.tag}** (${msg.author.id}) \n\n`; if (errorMessage) { if (errorMessage.length > 0) { - sendErr = sendErr + errorMessage+'\n'; - inLogChannel = errorMessage+'\n'; + sendErr = sendErr + errorMessage + '\n'; + inLogChannel = errorMessage + '\n'; } } - if (sendTheError) { - sendErr = sendErr+'```js\n'+theError.stack+'```'; - } - if (notify || !client) { - msg.channel.send(sendErr.trim(),{split:true}).catch(noPerm(msg)); - } + if (sendTheError) sendErr = sendErr + '```js\n' + theError.stack + '```'; + if (notify) ret = await msg.channel.send(sendErr.trim(), { split: true }).catch(noPerm(msg)); } if (client) { + inLogChannel = inLogChannel + '```js\n' + theError.stack + '```'; try { - inLogChannel = inLogChannel+'```js\n'+theError.stack+'```'; const sendAt = client.channels.cache.get(defaultErrorLogChannel); - sendAt.send(logThis + inLogChannel.trim() + timestampAt(client),{split:{maxLength:4000,char: "\n",append:'```',prepend:'```js\n'}}); - } catch (errmes) { - console.error(errmes); + sendAt.send(logThis + inLogChannel.trim() + timestampAt(client), { split: { maxLength: 2000, char: "\n", append: '```', prepend: '```js\n' } }); + } catch { + return console.error("Can't log to error channel or not configured.", timestampAt() + ":", theError); } } + return ret; } /** * Get message object from the message channel or provided channel * @param {Message} msg - Message object (msg) - * @param {String} MainID - Message ID | Channel ID | Channel Mention + * @param {String} MainID - Message ID | Channel_[mention|ID] | Message link * @param {String} SecondID - Message ID * @returns {Promise} Message object | undefined */ async function getChannelMessage(msg, MainID, SecondID) { - if (!MainID || !msg) { - return; - } + if (!MainID || !msg) return; if (/\//.test(MainID)) { const splitURL = MainID.split(/\/+/); - SecondID = splitURL[splitURL.length-1]; - MainID = splitURL[splitURL.length-2]; + SecondID = splitURL[splitURL.length - 1]; + MainID = splitURL[splitURL.length - 2]; } MainID = cleanMentionID(MainID); if (SecondID && !/\D/.test(SecondID)) { try { - const meschannel = msg.client.channels.cache.get(MainID); + const meschannel = (msg.client.owners.includes(msg.author) ? msg.client : msg.guild).channels.cache.get(MainID); return meschannel.messages.fetch(SecondID); - } catch (theError) { - return + } catch { + return; } } else { - return msg.channel.messages.fetch(MainID).catch(() => {}); + return msg.channel.messages.fetch(MainID).catch(() => { }); } } function execCB(error, stdout, stderr) { if (error) { - console.error(error); return errLog(error); } - console.log('stdout:\n'+stdout); - console.log('stderr:\n'+stderr); + console.log('stdout:\n' + stdout); + console.log('stderr:\n' + stderr); } /** @@ -91,18 +86,18 @@ function execCB(error, stdout, stderr) { */ async function ranLog(msg, addition) { const channel = msg.client.channels.cache.get(ranLogger), - ifCode = addition.startsWith("```") && addition.endsWith("```"); + ifCode = addition.startsWith("```") && addition.endsWith("```"); const addSplit = splitOnLength((addition.substr(ifCode ? 2045 : 2049)).split(","), 1010, ","); - const embed = await defaultImageEmbed(msg, null, msg.command.name.toLocaleUpperCase() + ` (${msg.id})`); - embed.setAuthor(msg.author.tag + ` (${msg.author.id})`, msg.author.displayAvatarURL({format: "png", size: 4096, dynamic: true})) - .setURL(msg.url) - .setDescription(addition.slice(0, ifCode && addSplit[0]?.[0].length > 0 ? 2044 : 2048) + (ifCode && addSplit[0]?.[0].length > 0 ? "```" : "")); + const embed = defaultImageEmbed(msg, null, msg.command.name.toLocaleUpperCase() + ` ${msg.id}`); + embed.setAuthor(msg.author.tag + ` (${msg.author.id})`, msg.author.displayAvatarURL({ format: "png", size: 128, dynamic: true })) + .setURL(msg.url) + .setDescription(addition.slice(0, ifCode && addSplit[0]?.[0].length > 0 ? 2044 : 2048) + (ifCode && addSplit[0]?.[0].length > 0 ? "```" : "")); if (addSplit[0]?.[0].length > 0) for (const add of addSplit) embed.addField("​", "```js\n" + add.join(",") + (embed.fields.length < (addSplit.length - 1) ? ",```" : "")); - embed.setFooter(timestampAt(msg.client), msg.guild?.iconURL({"size": 4096, "dynamic": true})); + embed.setFooter(timestampAt(msg.client), msg.guild?.iconURL({ format: "png", size: 128, dynamic: true })); if (msg.guild) embed.addField("Guild", `\`${msg.guild?.name}\`\n(${msg.guild?.id})`, true); embed.addField("Channel", (msg.guild ? `<#${msg.channel.id}>\n\`${msg.channel?.name}\`` : `**DM**\n\`${msg.channel.recipient.tag}\``) + `\n(${msg.channel.id})`, true) - .addField("User", `<@!${msg.author.id}>`, true); - trySend(msg.client, channel, {embed: embed}); + .addField("User", `<@!${msg.author.id}>`, true); + trySend(msg.client, channel, { embed: embed }); } /** @@ -115,27 +110,19 @@ async function ranLog(msg, addition) { * @returns {String} */ function multipleMembersFound(msg, arr, key, max = 4, withID) { - if (msg && arr.length > 0) { + if (msg && arr.length > 1) { try { let multipleFound = []; - for(const one of arr) { + for (const one of arr) { const user = one.user ?? one; let mes = user.tag; - if (withID) { - mes = mes + ` (${user.id})`; - } + if (withID) mes = mes + ` (${user.id})`; multipleFound.push(mes); } let multi = []; - for(const mu of multipleFound) { - if (multipleFound.indexOf(mu) < max) { - multi.push(mu); - } - } + for (const mu of multipleFound) if (multipleFound.indexOf(mu) < max) multi.push(mu); let mes = multi.join(",\n' "); - if (multipleFound.length > max) { - mes = mes+`,\n' ${multipleFound.length - max} more...`; - } + if (multipleFound.length > max) mes = mes + `,\n' ${multipleFound.length - max} more...`; return `Multiple members found for: **${key}**\`\`\`js\n' ${mes}\`\`\``; } catch (e) { errLog(e, msg, msg.client); @@ -147,27 +134,25 @@ function multipleMembersFound(msg, arr, key, max = 4, withID) { /** * Get member object with RegExp - * @param {Message | GuildMember} msg Object of the guild being searched - * @param {String} name Keyword + * @param {Message | GuildMember | Guild} base Object of the guild being searched + * @param {String} key Keyword * @returns {GuildMember[]} Member object found */ -function findMemberRegEx(msg, name) { - if (!(msg ?? name)) { - return; - } - const re = new RegExp(name, "i"); - return msg.guild?.members.cache.array().filter(r => re.test(r.displayName) || re.test(r.user.tag)); +function findMemberRegEx(base, key) { + if (!base || !key) return; + const re = new RegExp(key, "i"); + return (base.guild ?? base).members.cache.map(r => r).filter(r => re.test(r.displayName) || re.test(r.user.tag)); } /** * React when it try something but fail because has not enough perms * @param {Message} msg */ -function noPerm(msg) { - if (!msg) { - return; - } - msg.react("sadduLife:797107817001386025").catch(() => {}); +async function noPerm(msg) { + if (!msg) return; + try { + return msg.react("sadduLife:797107817001386025"); + } catch { } } /** @@ -175,92 +160,70 @@ function noPerm(msg) { * @param {CommandoClient} client - (this.client) * @param {Message | String | TextChannel | DMChannel} msgOrChannel Message object | channel_ID * @param {MessageOptions} content - ({content:content,optionblabla}) - * @param {Boolean} adCheck - Check source for Discord invite link (true) + * @param {Boolean} checkAd - Check source for Discord invite link (true) * @returns {Promise} Sent message object */ -async function trySend(client, msgOrChannel, content, adCheck = true) { +async function trySend(client, msgOrChannel, content, checkAd = true) { /*if (content instanceof MessageEmbed) { let fLength = []; - for (const f of content.fields) { - fLength.push(f.value.length); - } + for (const f of content.fields) fLength.push(f.value.length); console.log("Embed", content.title, timestampAt(client), "\n", content.description, content.description?.length, "\n", content.fields, fLength) }*/ - if (!client || !msgOrChannel) { - return; - } - if (typeof msgOrChannel === "string") { - msgOrChannel = client.channels.cache.get(msgOrChannel); - }; - msgOrChannel.channel?.startTyping() || msgOrChannel.startTyping(); + if (!client || !msgOrChannel) return; + if (typeof msgOrChannel === "string") msgOrChannel = client.channels.cache.get(msgOrChannel); + if (!client.user.typingIn(msgOrChannel.channel || msgOrChannel)) (msgOrChannel.channel || msgOrChannel).startTyping(); if (client.owners.includes(msgOrChannel.author)) { - adCheck = false; - if (content.disableMentions) { - content.disableMentions = "none"; - } + checkAd = false; + if (content.disableMentions) content.disableMentions = "none"; } - if (adCheck) { + if (checkAd) { if (content.content) { - content.content = sentAdCheck(content.content); + content.content = adCheck(content.content); } else { - if (typeof content === "string") { - content = sentAdCheck(content); - } - } - } - if (msgOrChannel instanceof Message) { - const ret = await msgOrChannel.channel.send(content).catch(() => { - noPerm(msgOrChannel); - msgOrChannel.channel.stopTyping(); - }); - msgOrChannel.channel.stopTyping(); - return ret; - } else { - if ((msgOrChannel instanceof TextChannel) || (msgOrChannel instanceof DMChannel)) { - const ret = await msgOrChannel.send(content).catch((e) => { - errLog(e, null, client); - msgOrChannel.stopTyping(); - }); - msgOrChannel.stopTyping(); - return ret; - } else { - errLog(e, null, client, false, "[TRYSEND] Invalid {msgOrChannel} type.```js\n" + JSON.stringify(msgOrChannel, (k, v) => v ?? undefined, 2) + "```"); + if (typeof content === "string") content = adCheck(content); } } + if (!((msgOrChannel instanceof Message) || (msgOrChannel instanceof TextChannel) || (msgOrChannel instanceof DMChannel))) return errLog(e, null, client, false, "[TRYSEND] Invalid {msgOrChannel} type.```js\n" + JSON.stringify(msgOrChannel, (k, v) => v ?? undefined, 2) + "```"); + const ret = await (msgOrChannel.channel || msgOrChannel).send(content).catch(/*msgOrChannel.channel ? noPerm(msgOrChannel) :*/ e => errLog(e, msgOrChannel, client)); + await (msgOrChannel.channel || msgOrChannel).stopTyping(); + return ret; } /** * Delete message * @param {Message} msg - Message to delete (msg) */ -function tryDelete(msg) { - if (!msg) { - return; +async function tryDelete(msg) { + if (!msg) return; + try { + return msg.delete(); + } catch (e) { + throw e; } - msg.delete().catch(e => {throw e}); } - /** - * React message - * @param {Message} msg - Message to react (msg) - * @param {String} reaction - Emote ("name:ID") - */ -function tryReact(msg, reaction) { - if (!msg || reaction.length === 0) { - return; +/** + * React message + * @param {Message} msg - Message to react (msg) + * @param {String} reaction - Emote ("name:ID") + */ +async function tryReact(msg, reaction) { + if (!msg || !reaction || reaction.length === 0) return; + try { + return msg.react(reaction); + } catch (e) { + throw e; } - msg.react(reaction).catch(e => {throw e}); } /** * Check message's content for ads * @param {String} content - Content to check */ -function sentAdCheck(content) { +function adCheck(content) { if (content.length > 5) { - if (/(https:\/\/)?(www\.)?discord\.gg\/(?:\w{2,15}(?!\w)(?= *))/.test(content)) { - content = content.replace(/(https:\/\/)?(www\.)?discord\.gg\/(?:\w{2,15}(?!\w)(?= *))/, '`Some invite link goes here`'); - } + if (/(https:\/\/)?(www\.)?discord\.gg\/(?:\w{2,15}(?!\w)(?= *))/.test(content)) content = content + .replace(/(https:\/\/)?(www\.)?discord\.gg\/(?:\w{2,15}(?!\w)(?= *))/g, '`Some invite link goes here`'); } return content; } @@ -272,18 +235,16 @@ function sentAdCheck(content) { * @param {GuildMember | User} author * @param {String} title * @param {String} footerQuote - * @returns {Promise} + * @returns {MessageEmbed} */ -async function defaultImageEmbed(msg, image, title, footerQuote) { - if (!footerQuote) { - const r = await database.collection(msg.guild ? "Guild" : "User").findOne({document: msg.guild?.id ?? msg.author?.id}).catch(() => {}); - footerQuote = r?.["settings"]?.defaultEmbed?.footerQuote || ""; - } - return new MessageEmbed() - .setTitle(title) - .setImage(image) - .setColor(msg.guild ? getColor(msg.member?.displayColor) : randomColors[Math.floor(Math.random() * randomColors.length)]) - .setFooter(footerQuote); +function defaultImageEmbed(msg, image, title, footerQuote) { + if (!footerQuote) footerQuote = (msg.guild ?? msg.author).defaultEmbed?.footerQuote || ""; + const emb = new MessageEmbed() + .setImage(image) + .setColor(msg.guild ? getColor(msg.member?.displayColor) : randomColors[Math.floor(Math.random() * randomColors.length)]) + .setFooter(footerQuote); + if (title) emb.setTitle(title); + return emb; } /** @@ -292,35 +253,26 @@ async function defaultImageEmbed(msg, image, title, footerQuote) { * @returns {String} Clean ID */ function cleanMentionID(key) { - if (!key) { - return; - } + if (!key || (typeof key !== "string")) return; let uID = key.trim(); - if (!/\D/.test(uID)) { - return uID; - } - if (uID.startsWith('<@') || uID.startsWith('<#')) { - uID = uID.slice(2); - } - if (uID.endsWith('>')) { - uID = uID.slice(0,-1) - } - if (uID.startsWith('!') || uID.startsWith("@") || uID.startsWith("#") || uID.startsWith('&')) { - uID = uID.slice(1); - } + if (!/\D/.test(uID)) return uID; + if (uID.startsWith('<@') || uID.startsWith('<#')) uID = uID.slice(2); + if (uID.endsWith('>')) uID = uID.slice(0, -1); + if (uID.startsWith('!') || uID.startsWith("@") || uID.startsWith("#") || uID.startsWith('&')) uID = uID.slice(1); return uID; } /** * Get channel object wit RegExp - * @param {Message | GuildMember} msg Object of the guild being searched + * @param {Message | GuildMember | Guild} msg Object of the guild being searched * @param {String} name Keyword * @param {ChannelType[]} exclude Exclude channel type * @returns {GuildChannel[]} Channels object found */ function findChannelRegEx(msg, name, exclude) { + if (!msg || !name) return; const re = new RegExp(name, "i"); - return msg.guild?.channels.cache.array().filter(r => { + return (msg.guild || msg).channels.cache.map(r => r).filter(r => { if (exclude?.includes(r.type)) { return false; } else { @@ -336,8 +288,9 @@ function findChannelRegEx(msg, name, exclude) { * @returns {Role[]} Roles object found */ function findRoleRegEx(msg, name) { + if (!msg.guild || !name) return; const re = new RegExp(name, "i"); - return msg.guild?.roles.cache.array().filter(r => re.test(r.name)); + return msg.guild.roles.cache.map(r => r).filter(r => re.test(r.name)); } /** @@ -350,26 +303,18 @@ function findRoleRegEx(msg, name) { * @returns {String} */ function multipleChannelsFound(msg, arr, key, max = 4, withID) { - if (arr.length > 0) { + if (msg && arr.length > 1) { try { let multipleFound = []; - for(const one of arr) { + for (const one of arr) { let mes = one.name; - if (withID) { - mes = mes + ` (${one.id})`; - } + if (withID) mes = mes + ` (${one.id})`; multipleFound.push(mes); } let multi = []; - for(const mu of multipleFound) { - if (multipleFound.indexOf(mu) < max) { - multi.push(mu); - } - } + for (const mu of multipleFound) if (multipleFound.indexOf(mu) < max) multi.push(mu); let mes = multi.join(",\n' "); - if (multipleFound.length > max) { - mes = mes+`,\n' ${multipleFound.length - max} more...`; - } + if (multipleFound.length > max) mes = mes + `,\n' ${multipleFound.length - max} more...`; return `Multiple channels found for: **${key}**\`\`\`js\n' ${mes}\`\`\``; } catch (e) { errLog(e, msg, msg.client); @@ -388,27 +333,19 @@ function multipleChannelsFound(msg, arr, key, max = 4, withID) { * @param {Boolean} withID - Include role_ID * @returns {String} */ - function multipleRolesFound(msg, arr, key, max = 4, withID) { - if (arr.length > 0) { +function multipleRolesFound(msg, arr, key, max = 4, withID) { + if (msg && arr.length > 1) { try { let multipleFound = []; - for(const one of arr) { + for (const one of arr) { let mes = one.name; - if (withID) { - mes = mes + ` (${one.id})`; - } + if (withID) mes = mes + ` (${one.id})`; multipleFound.push(mes); } let multi = []; - for(const mu of multipleFound) { - if (multipleFound.indexOf(mu) < max) { - multi.push(mu); - } - } + for (const mu of multipleFound) if (multipleFound.indexOf(mu) < max) multi.push(mu); let mes = multi.join(",\n' "); - if (multipleFound.length > max) { - mes = mes+`,\n' ${multipleFound.length - max} more...`; - } + if (multipleFound.length > max) mes = mes + `,\n' ${multipleFound.length - max} more...`; return `Multiple roles found for: **${key}**\`\`\`js\n' ${mes}\`\`\``; } catch (e) { errLog(e, msg, msg.client); @@ -420,30 +357,43 @@ function multipleChannelsFound(msg, arr, key, max = 4, withID) { /** * Standard - * @param {Message} msg - Message object + * @param {Message | Guild} msg - Message object * @param {String} key - Channel ID | Mention | Name + * @param {ChannelType[]} exclude - Exclude channel type * @returns {GuildChannel | Channel} Channel object */ -function getChannelProchedure(msg, key) { - if (key.length === 0) { - return; - } +function getChannel(msg, key, exclude) { + if (!key || key.length === 0 || !msg) return; const search = cleanMentionID(key); - if (search.length === 0) { - return; - } + if (search.length === 0) return; let channel; if (/^\d{17,19}$/.test(search)) { - channel = msg.guild?.channels.cache.get(search); - if (!channel && msg.client.owners.includes(msg.author)) { - channel = msg.client.channels.cache.get(search); - } - } - if (!channel) { - channel = findChannelRegEx(msg, search, ["category", "voice"])?.[0]; + channel = (msg.guild || msg).channels.cache.get(search); + if (!channel && msg.client.owners.includes(msg.author)) channel = msg.client.channels.cache.get(search); } + if (!channel) channel = findChannelRegEx(msg, search, exclude)?.[0]; return channel; } + +/** + * Get guild member using name || tag || ID + * @param {Guild} guild + * @param {String} key - name || tag || ID + * @returns {GuildMember[]} + */ +function getMember(guild, key) { + if (!guild) return; + const use = cleanMentionID(key); + let found = []; + if (!use || use.length === 0) return; + if (/^\d{17,19}$/.test(use)) { + found.push(guild.member(use)); + } else { + found = findMemberRegEx(guild, use); + } + return found; +} + /** * Compare 2 different timestamp * @param {Number} compare - Number to compare @@ -452,6 +402,7 @@ function getChannelProchedure(msg, key) { function getUTCComparison(compare) { return compare - new Date().valueOf(); } + /** * Make guild's event log embed with author and footer * @param {Guild} guild @@ -459,8 +410,9 @@ function getUTCComparison(compare) { */ function defaultEventLogEmbed(guild) { return new MessageEmbed() - .setAuthor(guild.name, guild.iconURL({size:4096, dynamic: true})) - .setFooter((guild.defaultEmbed?.footerQuote ? guild.defaultEmbed.footerQuote + "・" : "") + new Date(new Date().valueOf() + (guild.client.matchTimestamp ?? 0)).toUTCString().slice(0, -4)); + .setAuthor(guild.name) + .setFooter((guild.defaultEmbed?.footerQuote ? guild.defaultEmbed.footerQuote : ""), guild.iconURL({ format: "png", size: 128, dynamic: true })) + .setTimestamp(new Date()); } /** @@ -478,17 +430,57 @@ function splitOnLength(arr, maxLength, joiner = "\n") { } else { pushed++; } - if (!toField[i] || toField[i].length === 0) { - toField[i] = []; - } + if (!toField[i] || toField[i].length === 0) toField[i] = []; toField[i].push(res); - if (!arr[pushed]) { - break; - } + if (!arr[pushed]) break; } return toField; } +/** + * Parse string (split ",") + * @param {String} content + * @returns {String[]} + */ +function parseComa(content) { + return content.trim().split(/(? r.newPage()); -page1.then(r => r.goto(URL[1]).catch(console.error)); - -/** - * Chat with Shasha - * @param {Commando.Client} client - (this.client) - * @param {Number} index - Index of answer - * @param {Commando.Message} question - Message object - * @returns {Promise} Reply - * -async function shaChat(client, index, question) { - if (page1) { - let query = question.content.trim(); - if (query.toLowerCase().startsWith(client.commandPrefix+"chat")) { - query = query.slice((client.commandPrefix+"chat").length).trim(); - } - try { - const page = await page1; - //console.log("New chat query: "+query); - await page.waitForSelector("input[id=\"question\"]"); - await page.type("input[id=\"question\"]", query); - await page.keyboard.press("Enter"); - return fetchAnswer(page, index); - } catch (error) { - throw error; - } - } -} - -/** - * @param {puppeteer.Page} page - * @param {Number} index - * @returns {String} - * -async function fetchAnswer(page, index) { - try { - await page.waitForSelector(`#answer > div:nth-child(${index})`).catch(() => {}); - const result = await page.evaluate((index) => { - const res = document.querySelector(`#answer > div:nth-child(${index})`).childNodes[4].textContent; - return res; - }, index); - return result; - } catch (e) { - throw e; - } -} - -let chatIndex = 3; +]; */ -/** - * @param {String} message - Query - * @returns {Promise} Answers - */ - async function chatAnswer(message) { - const r = await axios.post("https://rebot.me/ask", { username: "muffin-6", question: message }).catch(() => {}); - return r.data; - } /* { - //console.log(message.content); - //console.log(chatIndex); - if (message.content.trim().length === 0) { - return - } else { - try { - message.channel.startTyping(); - await shaChat(client, chatIndex, message).then(async answer => { - chatIndex += 2; - if (message.channel.lastMessage.author === client.user && answer?.trim() === message.channel.lastMessage.content.trim()) { - return trySend(client, message, "Please speak one by one, I'm overwhelmed <:catstareLife:794930503076675584>"); - } else { - trySend(client, message, answer.trim()).then(() => { - message.channel.stopTyping(); - }).catch(e => { - noPerm(message); - message.channel.stopTyping(); - }); - } - return //ranLog(message, message.content.trim(), answer); - }).catch(e => { - noPerm(message); - message.channel.stopTyping(); - }); - } catch (e) { - noPerm(message); - message.channel.stopTyping(); - } - } -} -async function fixChat() { - return page1.then(r => r.reload()).then(() => {return chatIndex = 3}).catch(e => {return console.log(e)}); -} */ + async function chatAnswer(message) { + return axios.post("https://rebot.me/ask", { username: "muffin-6", question: message }).then(r => r.data).catch(() => {}); + } module.exports = { chatAnswer } diff --git a/resources/structures.js b/resources/structures.js index 487be3b..5d01f85 100644 --- a/resources/structures.js +++ b/resources/structures.js @@ -10,19 +10,20 @@ Structures.extend("Guild", g => { super(client, data); this.dbLoaded = false; } + async dbLoad() { - const ret = await database.collection("Guild").findOne({document: this.id}).then((r, j) => { + return database.collection("Guild").findOne({document: this.id}).then((r, j) => { if (j) return errLog(j, null, this.client); - this.infractions = r?.moderation?.infractions; - this.moderation = r?.moderation?.settings; - this.defaultEmbed = r?.settings?.defaultEmbed; - this.quoteOTD = r?.settings?.quoteOTD; - this.eventChannels = r?.settings?.eventChannels; + this.infractions = r?.moderation?.infractions || []; + this.moderation = r?.moderation?.settings || {}; + this.defaultEmbed = r?.settings?.defaultEmbed || {}; + this.quoteOTD = r?.settings?.quoteOTD || {}; + this.eventChannels = r?.settings?.eventChannels || {}; return this.dbLoaded = true; }); - return ret; } + /** * Get user infractions * @param {String} get - User ID @@ -46,49 +47,57 @@ Structures.extend("Guild", g => { return found; } catch (e) { } } + + async setDescription(set) { + return database.collection("Guild").updateOne({document: this.id}, { $set: { description: set }, $setOnInsert: { document: this.id }}, {upsert: true}, (e, r) => { + if (e) return errLog(e, null, this.client); + this.description = set; + return true; + }); + } + async addInfraction(add) { try { const r = await database.collection("Guild").findOne({ document: this.id }); this.infractions = r?.moderation?.infractions; - const ret = await database.collection("Guild").updateOne({document: this.id}, {$push:{"moderation.infractions":add}}, (e) => { + return database.collection("Guild").updateOne({document: this.id}, {$push:{"moderation.infractions":add}}, (e) => { if (e) return errLog(e, null, this.client); this.infractions.push(add); return true; }); - return ret; } catch (e) { } } + async setQuoteOTD(set) { - const ret = await database.collection("Guild").updateOne({document: this.id}, {$set: {"settings.quoteOTD": set}, $setOnInsert: { document: this.id }}, {upsert: true}, (e) => { + return database.collection("Guild").updateOne({document: this.id}, {$set: {"settings.quoteOTD": set}, $setOnInsert: { document: this.id }}, {upsert: true}, (e) => { if (e) return errLog(e, null, this.client); this.quoteOTD = set; return true; }); - return ret; } + async setEventChannels(set) { - const ret = await database.collection("Guild").updateOne({document: this.id}, {$set: {"settings.eventChannels": set}, $setOnInsert: { document: this.id }}, {upsert: true}, (e) => { + return database.collection("Guild").updateOne({document: this.id}, {$set: {"settings.eventChannels": set}, $setOnInsert: { document: this.id }}, {upsert: true}, (e) => { if (e) return errLog(e, null, this.client); this.eventChannels = set; return true; }); - return ret; } + async setDefaultEmbed(set) { - const ret = await database.collection("Guild").updateOne({document: this.id}, {$set:{"settings.defaultEmbed": set}, $setOnInsert: { document: this.id }}, {upsert: true}, (e) => { + return database.collection("Guild").updateOne({document: this.id}, {$set:{"settings.defaultEmbed": set}, $setOnInsert: { document: this.id }}, {upsert: true}, (e) => { if (e) return errLog(e, null, this.client); this.defaultEmbed = set; return true; }); - return ret; } + async setModerationSettings(set) { - const ret = await database.collection("Guild").updateOne({document:this.id}, {$set:{"moderation.settings": set}, $setOnInsert: { document: this.id }}, {upsert: true}, (e) => { + return database.collection("Guild").updateOne({document:this.id}, {$set:{"moderation.settings": set}, $setOnInsert: { document: this.id }}, {upsert: true}, (e) => { if (e) return errLog(e, null, this.client); this.moderation = set; return true; }); - return ret; } } }); @@ -98,24 +107,42 @@ Structures.extend("User", u => { constructor(client, data) { super(client, data); this.dbLoaded = false; - this.giveHeart = "yes"; + this.cutie = true; } + async dbLoad() { - const ret = await database.collection("User").findOne({document: this.id}).then((r, j) => { - if (j) return errLog(j, null, this.client); - this.defaultEmbed = r?.settings?.defaultEmbed; + return database.collection("User").findOne({document: this.id}).then((r, e) => { + if (e) return errLog(e, null, this.client); + this.defaultEmbed = r?.settings?.defaultEmbed || {}; this.cachedAvatarURL = this.displayAvatarURL({format: "png", size: 4096, dynamic: true}); + this.interactions = r?.interactions || {}; + this.description = r?.description; return this.dbLoaded = true; }); - return ret; } + + async setInteractions(count) { + return database.collection("User").updateOne({document: this.id}, { $set: { interactions: count }, $setOnInsert: { document: this.id }}, {upsert: true}, (e, r) => { + if (e) return errLog(e, null, this.client); + this.interactions = count; + return true; + }); + } + + async setDescription(set) { + return database.collection("User").updateOne({document: this.id}, { $set: { description: set }, $setOnInsert: { document: this.id }}, {upsert: true}, (e, r) => { + if (e) return errLog(e, null, this.client); + this.description = set; + return true; + }); + } + async setDefaultEmbed(set) { - const ret = await database.collection("User").updateOne({document: this.id}, {$set:{"settings.defaultEmbed": set}, $setOnInsert: { document: this.id }}, {upsert: true}, (e) => { + return database.collection("User").updateOne({document: this.id}, {$set:{"settings.defaultEmbed": set}, $setOnInsert: { document: this.id }}, {upsert: true}, (e) => { if (e) return errLog(e, null, this.client); this.defaultEmbed = set; return true; }); - return ret; } } }); \ No newline at end of file diff --git a/resources/tCmd.js b/resources/tCmd.js new file mode 100644 index 0000000..35af304 --- /dev/null +++ b/resources/tCmd.js @@ -0,0 +1,24 @@ +'use strict'; + +const { join } = require("path"); +const requireAll = require("require-all"); + +module.exports = (client) => { + client.tCmds = requireAll({dirname: join(__dirname, "tCmds")}); + delete client.tCmds.resources; + process.stdin.on("data", stdinBuffer => { + // console.log(stdinBuffer.toJSON().data[0]); + const msg = stdinBuffer.toString().slice(0, -1).trim(); + if (!msg) return; + const cmd = msg.split(" ", 1)[0]; + let ex; + for (const c in client.tCmds) { + if (!c) return console.log("No command exist"); + if (c === cmd || client.tCmds[c].aliases?.includes(cmd)) { + ex = client.tCmds[c]; + break; + } + } + if (!ex) return console.log("No command:", cmd); else return ex.run(client, msg.slice(cmd.length).trim()); + }); +} \ No newline at end of file diff --git a/resources/tCmds/convo.js b/resources/tCmds/convo.js new file mode 100644 index 0000000..ad823ef --- /dev/null +++ b/resources/tCmds/convo.js @@ -0,0 +1,107 @@ +'use strict'; + +const emoteMessage = require("../emoteMessage"); +const { getChannel, parseDash, cleanMentionID, trySend } = require("../functions"); +const { getGuild } = require("./resources/functions"); +let a, G, C = [], last = 0, nO = "Args: [`-g` Guild: `[name|ID]`] `-c` Channel: `[name|ID]` [`-q` End current session | `-r` Resume previous session]"; +//const p = require("child_process"); + +module.exports = { + description: "Start a convo in a channel", + aliases: ["c"], + run(client, arg) { + if (!a) { + client.addListener("message", m => { + if (client.convo && C.map(r => r?.id).includes(m.channel.id)) { + if (!m.author.bot) last = C.indexOf(m.channel); + console.log(last + ":", m.channel.name, m.channel.id, m.author.id, m.author.tag + ":", m.cleanContent); + } + }); + a = true; + } + let num = parseInt(arg.match(/^\d+/)?.[0], 10), sl; + if (!num) num = last; else { + last = num; + sl = true; + }; + let U, H; + if (!arg) { + if (C.length > 0) { + console.log("Watching:"); + for (let i = 0; i < C.length; i++) console.log(i + ".", C[i].guild.name, C[i].name, C[i].id); + console.log("State:", client.convo || false); + } + return console.log(nO); + } + if (/(? r)); + // continue; + // } + C = client.channels.cache.map(r => r); + continue; + } + if (U === "ALL NOT GC") { + C = []; + continue; + } + if (G) { + C.push(getChannel(G, U, ["category", "voice"])); + } else { + if (H) console.log("No guild found:", H); + const U2 = cleanMentionID(U); + if (/^\d{17,19}$/.test(U2)) { + C.push(client.channels.cache.get(U2)); + } else { + const c = client.channels.cache.map(r => r); + C.push(c.filter(r => new RegExp(U2, "i").test(r.name))?.[0]); + } + } + } + if (u.startsWith("u ")) { + const n = parseInt(u.match(/\d+/), 10); + console.log("Removing", C[n].name, C[n].id); + return delete C[n]; + } + if (u === "r") { + if (C.length > 0) { + for (const a of C) console.log("Resuming session:", a.guild.name, a.guild.id, a.name, a.id); + return client.convo = true; + } else return console.log("No previous session"); + } + if (u === "q") { + if (C.length > 0 && client.convo) { + console.log("Ending sessions:"); + for (const a of C) console.log(a.guild.name, a.guild.id, a.name, a.id); + client.convo = false; + } + return console.log("Ended"); + } + } + if (!U || C.length === 0) { + if (G) { + console.log("Channels in:", G.name, G.id); + for (const k of G.channels.cache.map(r => r)) if (k.type != "category") console.log(k.name, k.id); + return; + } else { + if (U) return console.log("No channel found:", U, H && G ? "in guild: " + G.name + " " + G.id + " (" + H + ")" : ""); else return console.log("Provide channel"); + } + } + console.log("Session:"); + for (let i = 0; i < C.length; i++) console.log(C[i].guild.name, C[i].guild.id, i + ":", C[i].name, C[i].id); + } else if (C[num]) return C[num].send(emoteMessage(client, sl ? arg.slice(num?.toString().length).trim() : arg)).catch(console.error); else { + console.log('No session. Available sessions:'); + for (const a of C) console.log(a.guild.name, a.guild.id, a.name, a.id); + }; + return client.convo = true; + } +} \ No newline at end of file diff --git a/resources/tCmds/debug.js b/resources/tCmds/debug.js new file mode 100644 index 0000000..66cbe5d --- /dev/null +++ b/resources/tCmds/debug.js @@ -0,0 +1,23 @@ +'use strict'; + +const { timestampAt } = require("../debug"); +let a; + +module.exports = { + description: "Toggle debug mode", + aliases: ["d"], + run(client) { + if (!a) { + client.addListener("debug", (...args) => { + if (client.tDebug) console.log(...args, timestampAt()); + }); + a = true; + } + if (client.tDebug) { + client.tDebug = false; + return console.log("Debug disabled"); + } + client.tDebug = true; + return console.log("Debug enabled"); + } +} \ No newline at end of file diff --git a/resources/tCmds/eval.js b/resources/tCmds/eval.js new file mode 100644 index 0000000..dd482fc --- /dev/null +++ b/resources/tCmds/eval.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = { + description: "Execute JS codes", + aliases: ["e"], + async run(client, arg) { + return console.log(await eval(arg)); + } +} \ No newline at end of file diff --git a/resources/tCmds/exec.js b/resources/tCmds/exec.js new file mode 100644 index 0000000..35ee82b --- /dev/null +++ b/resources/tCmds/exec.js @@ -0,0 +1,11 @@ +'use strict'; + +const { exec } = require("child_process"); +const { execCB } = require("../functions"); + +module.exports = { + description: "Execute zsh terminal command", + run(client, arg) { + return exec(arg, execCB); + } +} \ No newline at end of file diff --git a/resources/tCmds/exit.js b/resources/tCmds/exit.js new file mode 100644 index 0000000..ac29f85 --- /dev/null +++ b/resources/tCmds/exit.js @@ -0,0 +1,6 @@ +module.exports = { + description: "Shutdown the bot", + run() { + process.exit(); + } +} \ No newline at end of file diff --git a/resources/tCmds/help.js b/resources/tCmds/help.js new file mode 100644 index 0000000..25b784d --- /dev/null +++ b/resources/tCmds/help.js @@ -0,0 +1,16 @@ +'use strict'; + +const { padEnd } = require("lodash"); + +module.exports = { + description: "Show help", + aliases: ["h"], + run(client) { + const h = []; + for (const a in client.tCmds) { + const r = client.tCmds[a]; + h.push(`${padEnd(a, 10, " ")}: ${r.description}`); + } + return console.log(h.join("\n")); + } +} \ No newline at end of file diff --git a/resources/tCmds/relogin.js b/resources/tCmds/relogin.js new file mode 100644 index 0000000..e87a025 --- /dev/null +++ b/resources/tCmds/relogin.js @@ -0,0 +1,11 @@ +'use strict'; + +const configFile = require("../../config.json"); + +module.exports = { + description: "Retry login", + aliases: ["re"], + run(client) { + return client.login(configFile.token).catch(console.error); + } +} \ No newline at end of file diff --git a/resources/tCmds/resources/functions.js b/resources/tCmds/resources/functions.js new file mode 100644 index 0000000..61edb72 --- /dev/null +++ b/resources/tCmds/resources/functions.js @@ -0,0 +1,21 @@ +'use strict'; + +const { cleanMentionID } = require("../../functions"); + +function findGuild(client, arg) { + const key = cleanMentionID(arg); + let guild; + if (/^\d{17,19}$/.test(key)) { + guild = client.guilds.cache.get(key); + } + if (!guild) { + guild = client.guilds.cache.map(r => r).filter(r => new RegExp(key, "i").test(r.name)); + } + return guild; +} + +function getGuild(client, arg) { + return findGuild(client, arg)?.[0]; +} + +module.exports = { getGuild } \ No newline at end of file diff --git a/resources/tCmds/resources/vina.js b/resources/tCmds/resources/vina.js new file mode 100644 index 0000000..0eb897a --- /dev/null +++ b/resources/tCmds/resources/vina.js @@ -0,0 +1,53 @@ +'use strict'; + +const axios = require("axios").default; +const r = { + content: "<:righthandLife:853255087963242526><:nekohmLife:846371737644957786><:lefthandLife:853255007700385874>", + /*embeds: [ + { + description: "<:nekoknifeLife:851287828453261322>", + image: { + url:"https://cdn.discordapp.com/attachments/822274053925503046/853624585539026954/unknown-10.png" + } + } + ], + components: [ + { + type: 1, + components: [ + { + type: 2, + style: 5, + label: "CLAIM YOUR 3 MONTHS NIRTO", + url: "https://discord.gg/M6eD4aYf" + },/* + { + type: 2, + style: 5, + label: "NOW", + url: "https://discord.gg/GcnKVjKJ49" + } + ] + } + ]*/ +} + +const em = { + embeds: [{ + title: null, + description: "" + }], +} +'<:righthandLife:853255087963242526><:nekohmLife:846371737644957786><:lefthandLife:853255007700385874>' +"<:nekosecretLife:853618590746279946>" +"<:nekoknifeLife:851287828453261322>" + + + + + + + + + +module.exports = (m) => axios.post("https://discord.com/api/webhooks/853603552668418068/AKTImj3fufUoUvqnSfHrufL3rgHUgcZHXS9WVE0zv7NkZ-gXL7Kg98qbOOg099_bav9H", { content: m }); diff --git a/resources/tCmds/vina.js b/resources/tCmds/vina.js new file mode 100644 index 0000000..22439ef --- /dev/null +++ b/resources/tCmds/vina.js @@ -0,0 +1,12 @@ +'use strict'; + +const vina = require("./resources/vina"), + emoteMessage = require("../emoteMessage"); + +module.exports = { + description: "Vina", + aliases: ["v"], + run(client, arg) { + return vina(emoteMessage(client, arg)); + } +} \ No newline at end of file