From 875dfe3166dc60b597f5d0abb82265103a925f61 Mon Sep 17 00:00:00 2001 From: Neko Life Date: Sun, 13 Jun 2021 23:55:17 +0000 Subject: [PATCH] permissions + eventLog --- Main.js | 146 ++++++++++---- cmds/fun/chat.js | 5 +- cmds/moderation/eventlog.js | 47 +++-- cmds/moderation/mute.js | 14 +- cmds/utility/avatar.js | 207 ++++++++++---------- cmds/utility/cloneembed.js | 2 +- cmds/utility/embmaker.js | 194 +++++++++++------- cmds/utility/lookup.js | 8 +- cmds/utility/mesemb.js | 6 +- cmds/utility/mesinfo.js | 10 +- cmds/utility/newquoteotd.js | 15 +- cmds/utility/quoteotd.js | 2 +- cmds/utility/say.js | 2 +- cmds/utility/send.js | 15 +- cmds/utility/setfootq.js | 24 +-- cmds/utility/uinfo.js | 8 +- resources/debug.js | 4 +- resources/eventsLogger/guildMemberAdd.js | 25 +++ resources/eventsLogger/guildMemberRemove.js | 28 +++ resources/eventsLogger/guildMemberUpdate.js | 51 +++++ resources/eventsLogger/message.js | 34 ++++ resources/eventsLogger/messageDelete.js | 40 ++++ resources/eventsLogger/messageUpdate.js | 35 ++++ resources/functions.js | 182 +++++++++++------ resources/structures.js | 35 ++-- 25 files changed, 755 insertions(+), 384 deletions(-) create mode 100644 resources/eventsLogger/guildMemberAdd.js create mode 100644 resources/eventsLogger/guildMemberRemove.js create mode 100644 resources/eventsLogger/guildMemberUpdate.js create mode 100644 resources/eventsLogger/message.js create mode 100644 resources/eventsLogger/messageDelete.js create mode 100644 resources/eventsLogger/messageUpdate.js diff --git a/Main.js b/Main.js index d26a78d..3735341 100644 --- a/Main.js +++ b/Main.js @@ -8,12 +8,20 @@ const client = new Commando.Client({ partials: ["CHANNEL", "GUILD_MEMBER", "MESSAGE", "REACTION", "USER"] }); const sqlite = require('sqlite'); -let configFile = require('./config.json'); -const { errLog, trySend, noPerm } = require('./resources/functions'); +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 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"); + client.registry .registerGroups([ 'utility', @@ -33,72 +41,128 @@ client.setProvider( }).then(db => new Commando.SQLiteProvider(db)) ).catch(e => errLog(e)); -const guildLog = "840154722434154496"; - client.on('ready', async () => { //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!'); }); client.on("message", async msg => { - if (msg.author.dbLoaded === false && !msg.author.bot) { - msg.author.dbLoad(); - } - if (msg.channel.id === "837178237322919966" && !msg.author.bot && !msg.isCommand) { - msg.channel.startTyping().then(trySend(client, msg, await chatAnswer(msg.cleanContent)) - ).then(msg.channel.stopTyping()).catch(msg.channel.stopTyping()); - } + if (!client.matchTimestamp) client.matchTimestamp = 0;//getUTCComparison(msg.createdTimestamp); + if (!msg.author.dbLoaded && !msg.author.bot) await msg.author.dbLoad(); + 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 (/(? { - if (r) { - trySend(client, msg, "YES! <3 <3"); - }; - }) - .catch(noPerm(msg)); - } - } - if (/(dont|don't|no).*giv.*(heart|nick).*(nick|heart)/i.test(msg.content)) { - if (msg.member.displayName?.endsWith(" <3")) { - msg.member.setNickname(msg.member.displayName.slice(0, -3)) - .then(r => { - if (r) { - trySend(client, msg, "okay <3"); - }; - }) - .catch(noPerm(msg)); - } - } - if (msg.guild.dbLoaded === false) { - msg.guild.dbLoad(); - } + if (!msg.guild.dbLoaded) await msg.guild.dbLoad(); + giveNickHeart(msg); } }); -client.on("guildMemberRemove", memberLeave => { - //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.`); +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); }); client.on("guildCreate", newShaGuild => { const shaGuild = client.guilds.cache.map(g => g); - trySend(client, guildLog, `Joined **${newShaGuild.name}** (${newShaGuild.id}) <:awamazedLife:795227334339985418> I'm in ${shaGuild.length} servers now.`); + trySend(client, configFile.guildLog, `Joined **${newShaGuild.name}** <:awamazedLife:795227334339985418> I'm in ${shaGuild.length} servers now.`); }); client.on("guildDelete", leaveShaGuild => { const shaGuild = client.guilds.cache.map(g => g); - trySend(client, guildLog, `Left **${leaveShaGuild.name}** (${leaveShaGuild.id}) <:WhenLife:773061840351657984> I'm in ${shaGuild.length} servers now.`); + trySend(client, configFile.guildLog, `Left **${leaveShaGuild.name}** <:WhenLife:773061840351657984> I'm in ${shaGuild.length} servers now.`); }); -client.on("guildMemberAdd", newMember => { +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); }); +client.on("messageDelete", async (msg) => { + 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); + } +}); + +client.on("messageUpdate", async (msgold, msgnew) => { + 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); + } +}); + +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); +}); + +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")); + trySend(client, log, emb); +}); + +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")); + trySend(client, log, emb); +}); + +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")); + trySend(client, log, emb); +}); + +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")); + trySend(client, log, emb); +}); + +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")); + trySend(client, log, emb); + errLog(e, null, client); +}); + +client.on("error", e => errLog(e, null, client)); +client.on("commandError", e => errLog(e, null, client)); + process.on("uncaughtException", e => errLog(e, null, client)); process.on("unhandledRejection", e => errLog(e, null, client)); process.on("warning", e => errLog(e, null, client)); diff --git a/cmds/fun/chat.js b/cmds/fun/chat.js index 7c22ed2..f9b32b1 100644 --- a/cmds/fun/chat.js +++ b/cmds/fun/chat.js @@ -13,7 +13,10 @@ module.exports = class chat extends commando.Command { description: "Lets chat!" }); } - async run(msg) { + async run(msg, args) { + if (args?.length === 0) { + 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(); diff --git a/cmds/moderation/eventlog.js b/cmds/moderation/eventlog.js index 3a5b886..dffd3a8 100644 --- a/cmds/moderation/eventlog.js +++ b/cmds/moderation/eventlog.js @@ -16,6 +16,9 @@ module.exports = class eventlog extends commando.Command { }); } async run(msg, arg) { + if (!msg.guild.dbLoaded) { + await msg.guild.dbLoad(); + } const set = arg.split(/(? 0) { - return trySend(this.client, msg, (await resultEmbed(this)).setDescription(report.slice(0, 2048))); - } + return trySend(this.client, msg, (await resultEmbed(this)).setDescription(report.slice(0, 2048))); } }; \ No newline at end of file diff --git a/cmds/moderation/mute.js b/cmds/moderation/mute.js index 072263a..abaa908 100644 --- a/cmds/moderation/mute.js +++ b/cmds/moderation/mute.js @@ -293,17 +293,11 @@ module.exports = class mute extends commando.Command { for (const user of targetUser) { const member = msg.guild.member(user); if (member) { - const pushIt = { - name:member.user.tag, - id:member.id, - roles:member.roles.cache.map(r => r.id) - } + const pushIt = member.toJSON(); + pushIt.roles = member.roles.cache.map(r => r.id); targetMember.push(pushIt); } else { - const pushIt = { - name: user.tag, - id:user.id - } + const pushIt = user.toJSON(); notInServer.push(pushIt); } } @@ -332,7 +326,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:2000,append:",```",prepend:"```js\n",char:","}}); + trySend(this.client, msg, {content:resultMsg+"```js\n" + JSON.stringify(infractionToDoc, null, 2) + "```",split:{maxLength:4000,append:",```",prepend:"```js\n",char:","}}); return } }; diff --git a/cmds/utility/avatar.js b/cmds/utility/avatar.js index 074b8b2..e3c9dde 100644 --- a/cmds/utility/avatar.js +++ b/cmds/utility/avatar.js @@ -2,8 +2,7 @@ const commando = require("@iceprod/discord.js-commando"); const { MessageEmbed } = require("discord.js"); -const { ranLog, errLog, trySend, findMemberRegEx, multipleMembersFound, cleanMentionID, tryReact } = require("../../resources/functions"); -const { database } = require("../../database/mongo"); +const { trySend, findMemberRegEx, multipleMembersFound, cleanMentionID, tryReact } = require("../../resources/functions"); const { randomColors } = require("../../config.json"); module.exports = class avatar extends commando.Command { @@ -17,124 +16,118 @@ module.exports = class avatar extends commando.Command { }); } async run(msg, arg) { - const doc = msg.guild?.id ?? msg.author.id; - const config = database.collection(msg.guild ? "Guild" : "User"); - config.findOne({document: doc}, async (docErr, r) => { - if (docErr) { - errLog(docErr, msg, this.client); + const doc = msg.guild ?? msg.author; + const footerQuote = doc.defaultEmbed?.footerQuote; + const args = arg.trim().split(/(? 1) { + tryReact(msg, "cathmmLife:772716381874946068"); } - const footerQuote = r?.["settings"]?.defaultEmbed?.footerQuote; - const args = arg.trim().split(/(? 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); } } - 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 (arg) { - for(const theAvThis of args) { - let avThis = theAvThis.replace(/\-\-show *\d*/i, ""); - let uID = cleanMentionID(avThis.trim()); - if (uID.length > 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 (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()}**`); - } - user = undefined; + } + if (arg) { + for(const theAvThis of args) { + let avThis = theAvThis.replace(/\-\-show *\d*/i, ""); + let uID = cleanMentionID(avThis.trim()); + if (uID.length > 0) { + let ree = []; + if (/^\d{17,19}$/.test(uID)) { + const findmem = msg.guild?.member(uID); + if (findmem) { + ree.push(findmem.user); } else { - dupliCheck.push(ree[0].id); - user = ree[0]; - multipleMemMes.push(multipleMembersFound(this.client, msg, ree.slice(1), uID, show)); + await 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 { user = undefined; - notFound += `Can't find user: **${avThis.trim()}**\n`; - } - if (user) { - avatar = user.displayAvatarURL({size:4096,dynamic:true}); - let emb = new MessageEmbed() - .setImage(avatar) - .setFooter(footerQuote ?? ""); - 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); - } - allEmb.push(emb); + } else { + dupliCheck.push(ree[0].id); + user = ree[0]; + multipleMemMes.push(multipleMembersFound(msg, ree.slice(1), uID, show)); } + } else { + user = undefined; + notFound += `Can't find user: **${avThis.trim()}**\n`; } - if (onceOnly) { - break + if (user) { + avatar = user.displayAvatarURL({format: "png", size: 4096, dynamic: true}); + let emb = new MessageEmbed() + .setImage(avatar) + .setFooter(footerQuote ?? ""); + 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); + } + allEmb.push(emb); } } - } else { - let emb = new MessageEmbed() - .setTitle(user.displayName ?? user.username) - .setImage(avatar) - .setFooter(footerQuote ?? ""); - if (user.displayColor) { - emb.setColor(user.displayColor); + if (onceOnly) { + break } - 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); + } else { + let emb = new MessageEmbed() + .setTitle(user.displayName ?? user.username) + .setImage(avatar) + .setFooter(footerQuote ?? ""); + if (user.displayColor) { + emb.setColor(user.displayColor); } - for (let index = 0; index < allEmb.length; index++) { - const embelement = allEmb[index]; - const contelement = multipleMemMes[index]; - retSent.push({ embed: embelement, content: contelement, split:{maxLength:2000,char: ",",append:',```',prepend:'```js' }}); + if (!msg.guild) { + emb.setColor(randomColors[Math.floor(Math.random() * randomColors.length)]); } - return retSent.map(r => trySend(this.client, msg, r)); - }); + if (emb.color === 16777215) { + emb.setColor(16777214); + } + allEmb.push(emb); + } + let retSent = []; + 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' }}); + } + return retSent.map(r => trySend(this.client, msg, r)); } }; \ No newline at end of file diff --git a/cmds/utility/cloneembed.js b/cmds/utility/cloneembed.js index 362b879..4a47b7f 100644 --- a/cmds/utility/cloneembed.js +++ b/cmds/utility/cloneembed.js @@ -17,7 +17,7 @@ module.exports = class cloneembed extends commando.Command { async run(msg, cargs) { const args = cargs.trim().split(/ +/); try { - const theMes = await getChannelMessage(this.client,msg,args[0],args[1]); + const theMes = await getChannelMessage(msg,args[0],args[1]); let content; if (theMes.content) { content = theMes.content; diff --git a/cmds/utility/embmaker.js b/cmds/utility/embmaker.js index df9f2cc..f9e4859 100644 --- a/cmds/utility/embmaker.js +++ b/cmds/utility/embmaker.js @@ -1,8 +1,8 @@ 'use strict'; const commando = require("@iceprod/discord.js-commando"); -const { MessageEmbed } = require("discord.js"); -const { ranLog, errLog, getChannelMessage, noPerm, tryReact, findChannelRegEx, trySend, cleanMentionID } = require("../../resources/functions"); +const { MessageEmbed, GuildChannel } = require("discord.js"); +const { ranLog, errLog, getChannelMessage, noPerm, tryReact, trySend, cleanMentionID, getChannelProchedure, sentAdCheck } = require("../../resources/functions"); const getColor = require("../../resources/getColor"); module.exports = class embmaker extends commando.Command { @@ -13,7 +13,20 @@ module.exports = class embmaker extends commando.Command { aliases: ["embedmaker","createmb","creatembed"], group: "utility", description: "Embed creator.", - details:`Embed creator: You can just copy this template and remove unneeded argument. Every argument is 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\`\`\`` + 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\`\`\`` }); } /** @@ -23,9 +36,15 @@ module.exports = class embmaker extends commando.Command { * @returns */ async run(msg, arg) { - if (msg.guild && !this.client.owners.includes(msg.author) && !msg.member.hasPermission("EMBED_LINKS")) { - return trySend(this.client, msg, "LMFAO no"); - } + 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(/(? 0) { - editSrc = await getChannelMessage(this.client, msg, editArg[0], editArg[1]); + editSrc = await getChannelMessage(msg, editArg[0], editArg[1]); if (editSrc) { const editEmb = editSrc.embeds[0]; if (editSrc.content) { @@ -83,15 +102,15 @@ module.exports = class embmaker extends commando.Command { if (value.toLowerCase().startsWith('quote')) { const quoteargs = value.slice('quote'.length).toLowerCase().trim().split(/ +/); if (quoteargs[0].length > 0) { - await getChannelMessage(this.client, msg, quoteargs[0], quoteargs[1]) + await getChannelMessage(msg, quoteargs[0], quoteargs[1]) .then(quoteThis => { if (quoteThis) { const author = quoteThis.member; autName = author ? author.displayName : quoteThis.author.username; - autIcon = quoteThis.author.displayAvatarURL({size:4096,dynamic:true}); + autIcon = quoteThis.author.displayAvatarURL({format: "png", size: 4096, dynamic: true}); autUrl = quoteThis.url; embed - .setAuthor(author ? author.displayName : quoteThis.author.username,quoteThis.author.displayAvatarURL({size:4096,dynamic:true}),quoteThis.url) + .setAuthor(author ? author.displayName : quoteThis.author.username,quoteThis.author.displayAvatarURL({format: "png", size: 4096, dynamic: true}),quoteThis.url) .setDescription(quoteThis.content) .setTimestamp(quoteThis.createdAt); if (author && author.displayColor) { @@ -134,22 +153,26 @@ module.exports = class embmaker extends commando.Command { continue; } if (value.toLowerCase().startsWith('title')) { - embed.setTitle(value.slice('title'.length).trim().replace(/\\(?!\\)/g,'')); + const use = value.slice('title'.length).trim().replace(/\\(?!\\)/g,''); + embed.setTitle(isAdmin ? use : sentAdCheck(use)); continue; } if (value.toLowerCase().startsWith('desc')) { - embed.setDescription(value.slice('desc'.length).trim().replace(/\\(?!\\)/g,'')); + const use = value.slice('desc'.length).trim().replace(/\\(?!\\)/g,''); + embed.setDescription(isAdmin ? use : sentAdCheck(use)); continue; } if (value.toLowerCase().startsWith('description')) { - embed.setDescription(value.slice('description'.length).trim().replace(/\\(?!\\)/g,'')); + 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(/( \-)+/); for(const autVal of autData) { if (autVal.toLowerCase().startsWith('name')) { - autName = autVal.slice('name'.length).trim().replace(/\\(?!\\)/g,''); + const use = autVal.slice('name'.length).trim().replace(/\\(?!\\)/g,''); + autName = isAdmin ? use : sentAdCheck(use); continue; } if (autVal.toLowerCase().startsWith('icon')) { @@ -162,6 +185,10 @@ module.exports = class embmaker extends commando.Command { continue; } if (autVal.toLowerCase().startsWith('url')) { + 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(); } else { @@ -200,6 +227,10 @@ module.exports = class embmaker extends commando.Command { continue; } if (value.toLowerCase().startsWith('url')) { + 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()); } else { @@ -233,17 +264,22 @@ module.exports = class embmaker extends commando.Command { continue; } if (value.toLowerCase().startsWith("timestamp")) { - if(!/\D/.test(value.slice("timestamp".length).trim())) { - embed.setTimestamp(parseInt(value.slice("timestamp".length).trim(), 10)); + const use = value.slice("timestamp".length).trim(); + if(!/\D/.test(use)) { + embed.setTimestamp(parseInt(use, 10)); } else { - if (value.slice("timestamp".length).trim().toLowerCase() === 'now') { + if (use.toLowerCase() === 'now') { embed.setTimestamp(msg.createdAt); } else { - embed.setTimestamp(value.slice("timestamp".length).trim()); + embed.setTimestamp(use); } } if (!embed.timestamp) { - reportMessage += "**[TIMESTAMP]** Invalid format.\n"; + if (use.length > 0) { + reportMessage += "**[TIMESTAMP]** Invalid format.\n"; + } else { + reportMessage += "**[TIMESTAMP]** Cleared.\n"; + } } continue; } @@ -251,7 +287,8 @@ module.exports = class embmaker extends commando.Command { const footerData = value.trim().split(/( \-)+/); for(const footval of footerData) { if (footval.toLowerCase().startsWith('text')) { - footertext = footval.slice("text".length).trim().replace(/\\(?!\\)/g,''); + const use = footval.slice("text".length).trim().replace(/\\(?!\\)/g,''); + footertext = isAdmin ? use : sentAdCheck(use); } if (footval.toLowerCase().startsWith('icon')) { if (/^https?:\/\/\w+\.\w\w/.test(footval.slice('icon'.length).trim())) { @@ -269,13 +306,16 @@ module.exports = class embmaker extends commando.Command { let fieldName,fieldValue, inline = false; for(const data of fieldData) { if (data.toLowerCase().startsWith('name')) { - fieldName = data.slice('name'.length).trim().replace(/\\(?!\\)/g,''); + const use = data.slice('name'.length).trim().replace(/\\(?!\\)/g,''); + fieldName = isAdmin ? use : sentAdCheck(use); } if (data.toLowerCase().startsWith('desc')) { - fieldValue = data.slice('desc'.length).trim().replace(/\\(?!\\)/g,''); + const use = data.slice('desc'.length).trim().replace(/\\(?!\\)/g,''); + fieldValue = isAdmin ? use : sentAdCheck(use); } if (data.toLowerCase().startsWith('description')) { - fieldValue = data.slice('description'.length).trim().replace(/\\(?!\\)/g,''); + const use = data.slice('description'.length).trim().replace(/\\(?!\\)/g,''); + fieldValue = isAdmin ? use : sentAdCheck(use); } if (data.toLowerCase().startsWith('inline')) { inline = true; @@ -285,13 +325,14 @@ module.exports = class embmaker extends commando.Command { fieldName = '​'; } if (!fieldValue) { - fieldValue = '​'; + fieldValue = '_ _'; } - embed.addField(fieldName,fieldValue,inline); + embed.addField(fieldName, fieldValue, inline); continue; } if (value.toLowerCase().startsWith('content')) { - content = value.slice('content'.length).trim().replace(/\\(?!\\)/g,''); + const use = value.slice('content'.length).trim().replace(/\\(?!\\)/g,''); + content = isAdmin ? use : sentAdCheck(use); continue; } if (value.toLowerCase().startsWith('channel')) { @@ -299,22 +340,17 @@ module.exports = class embmaker extends commando.Command { if (ID.toLowerCase() === 'here') { channel = msg.channel; } else { - if (/^\d{17,19}$/.test(ID)) { - channel = msg.guild.channels.cache.get(ID); - if (!channel && this.client.owners.includes(msg.author.id)) { - channel = this.client.channels.cache.get(ID); - } - } - if (!channel) { - channel = findChannelRegEx(msg, ID, ["category", "voice"])[0]; - } + channel = getChannelProchedure(msg, ID) if (!channel) { reportMessage += "**[CHANNEL]** Unknown channel.\n"; } else { - const p = msg.guild?.channels.cache.get(channel)?.permissionsFor(msg.author); - if (!p || p.missing("SEND_MESSAGES") || p.missing("EMBED_LINKS") || p.missing("VIEW_CHANNEL")) { - channel = undefined; - reportMessage += "**[CHANNEL]** Missing permission.\n"; + if ((channel instanceof GuildChannel) && !this.client.owners.includes(msg.author)) { + const p = channel.permissionsFor(msg.author).serialize(), + f = channel.permissionsFor(this.client.user).serialize(); + if (!p.EMBED_LINKS || !p.SEND_MESSAGES || !p.VIEW_CHANNEL || !f.EMBED_LINKS || !f.SEND_MESSAGES) { + channel = undefined; + reportMessage += "**[CHANNEL]** Missing permission.\n"; + } } } } @@ -350,11 +386,46 @@ module.exports = class embmaker extends commando.Command { } let sent = []; if (reportMessage.length > 0) { - sent.push(trySend(this.client, msg, reportMessage)); + sent.push(trySend(this.client, msg, reportMessage, !isAdmin)); } if (editSrc) { if (channel) { - if (msg.guild?.channels.cache.get(channel)?.permissionsFor(msg.author).has("ATTACH_FILES") && newAttach.length > 0) { + if (msg.guild && !this.client.owners.includes(msg.author)) { + if (channel.permissionsFor(msg.author).serialize().ATTACH_FILES && channel.permissionsFor(this.client.user).serialize().ATTACH_FILES && newAttach.length > 0) { + reportMessage += "**[ATTACHMENT]** Uploading attachments....\n"; + } else { + if (newAttach.length > 0) { + newAttach = []; + reportMessage += "**[ATTACHMENT]** Missing permission.\n"; + } + } + } + sent.push(trySend(this.client, channel, {content:content,embed:embed,files:newAttach})); + } else { + if (msg.guild) { + const c = msg.channel.permissionsFor(msg.author).serialize(), + f = msg.channel.permissionsFor(this.client.user).serialize(); + if (!c.ATTACH_FILES && !f.ATTACH_FILES) { + if (newAttach.length > 0) { + newAttach = []; + reportMessage += "**[ATTACHMENT]** Missing permission.\n"; + } + } + } + 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, {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})); + } + } + } else { + if (msg.guild && !this.client.owners.includes(msg.author)) { + if ((channel ?? msg.channel).permissionsFor(msg.author).serialize().ATTACH_FILES && (channel ?? msg.channel).permissionsFor(this.client.user).serialize().ATTACH_FILES && newAttach.length > 0) { reportMessage += "**[ATTACHMENT]** Uploading attachments....\n"; } else { if (newAttach.length > 0) { @@ -362,44 +433,15 @@ module.exports = class embmaker extends commando.Command { reportMessage += "**[ATTACHMENT]** Missing permission.\n"; } } - sent.push(channel.send({content:content,embed:embed,files:newAttach}).catch(e => noPerm(msg))); - } else { - channel = msg.channel; - if (msg.guild && channel.permissionsFor(msg.author).missing("ATTACH_FILES")) { - if (newAttach.length > 0) { - newAttach = []; - reportMessage += "**[ATTACHMENT]** Missing permission.\n"; - } - } - if (editSrc.author === this.client.user) { - sent.push(editSrc.edit({content:content,embed:embed,files:newAttach}).catch(e => { - errLog(e, msg, this.client); - try { - sent.push(channel.send('Something\'s wrong, i can\'t edit that so here <:WhenLife:773061840351657984>')); - sent.push(channel.send({content:content,embed:embed,files:newAttach})); - } catch (e) { - noPerm(msg); - } - })); - } else { - try { - sent.push(channel.send('I can\'t edit that, so here <:catstareLife:794930503076675584>')); - sent.push(channel.send({content:content,embed:embed,files:newAttach})); - } catch (e) { - noPerm(msg); - } - } } - } else { - if (!channel) { - channel = msg.channel; - } - sent.push(channel.send({content:content,embed:embed,files:newAttach}).catch(e => noPerm(msg))); + sent.push(trySend(this.client, channel ?? msg.channel, {content:content, embed:embed, files:newAttach}).catch(e => noPerm(msg))); } - if (sent.length > 0) { + if (await sent[0]) { tryReact(msg, "a:yesLife:794788847996370945"); + } else { + return noPerm(msg); } - ranLog(this.client, msg, ("```js\n" + JSON.stringify(embed, null, 2) + "```").slice(0, 2048)); + 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 715d047..47798de 100644 --- a/cmds/utility/lookup.js +++ b/cmds/utility/lookup.js @@ -37,7 +37,7 @@ module.exports = class lookup extends commando.Command { fetchedRoles = findRoleRegEx(msg, cleanRoleID); } if (fetchedRoles.length > 1) { - memMes = multipleRolesFound(this.client, msg, fetchedRoles, cleanRoleID, show, true); + memMes = multipleRolesFound(msg, fetchedRoles, cleanRoleID, show, true); } else { if (fetchedRoles.length === 0 || fetchedRoles[0] === null) { return trySend(this.client, msg, `No role found for: **${cleanRoleID}**`); @@ -55,7 +55,7 @@ module.exports = class lookup extends commando.Command { fetchedChannels = findChannelRegEx(msg, cleanChannelID); } if (fetchedChannels.length > 1) { - memMes = multipleChannelsFound(this.client, msg, fetchedChannels, cleanChannelID, show, true); + memMes = multipleChannelsFound(msg, fetchedChannels, cleanChannelID, show, true); } else { if (fetchedChannels.length === 0 || fetchedChannels[0] === null) { return trySend(this.client, msg, `No channel found for: **${cleanChannelID}**`); @@ -74,7 +74,7 @@ module.exports = class lookup extends commando.Command { fetchedMember = findMemberRegEx(msg, arg); } if (fetchedMember.length > 1) { - memMes = multipleMembersFound(this.client, msg, fetchedMember, arg, show, true); + memMes = multipleMembersFound(msg, fetchedMember, arg, show, true); } else { if (fetchedMember.length === 0 || fetchedMember[0] === null) { return trySend(this.client, msg, `No member found for: **${arg}**`); @@ -84,7 +84,7 @@ module.exports = class lookup extends commando.Command { } } if (memMes.length > 0) { - return trySend(this.client, msg, { content: memMes, split: { char: ",", append: ",```", prepend: "```js", maxLength: 2000 } }); + return trySend(this.client, msg, { content: memMes, split: { char: ",", append: ",```", prepend: "```js", maxLength: 4000 } }); } } }; \ No newline at end of file diff --git a/cmds/utility/mesemb.js b/cmds/utility/mesemb.js index b5c5ea3..fd46ba8 100644 --- a/cmds/utility/mesemb.js +++ b/cmds/utility/mesemb.js @@ -14,11 +14,11 @@ module.exports = class mesemb extends commando.Command { } async run(msg, arg) { const args = arg.trim().split(/ +/); - const message = await getChannelMessage(this.client,msg,args[0],args[1]); + const message = await getChannelMessage(msg, args[0], args[1]); if (!message) { return trySend(this.client, msg, "404 message not found!"); } - const mesemb = '```js\n'+JSON.stringify(message.embeds, null, 2)+'```'; - return trySend(this.client, msg, {content:'Collected:'+mesemb,split:{maxLength:2000,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: 4000, char: ",", append: ',```', prepend:'```js\n' }}); } }; \ No newline at end of file diff --git a/cmds/utility/mesinfo.js b/cmds/utility/mesinfo.js index 303571b..6189507 100644 --- a/cmds/utility/mesinfo.js +++ b/cmds/utility/mesinfo.js @@ -14,15 +14,15 @@ module.exports = class mesinfo extends commando.Command { } async run(msg, arg) { const args = arg.trim().split(/ +/); - const message = await getChannelMessage(this.client, msg, args[0], args[1]); + const message = await getChannelMessage(msg, args[0], args[1]); if (!message) { return trySend(this.client, msg, "No message with that ID <:catstareLife:794930503076675584>") } - const mesinfo = 'Collected:```js\n'+JSON.stringify(message, null, 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, null, 2)+'```'; - const Attachments = 'Attachments:```js\n'+JSON.stringify(message.attachments, null, 2)+'```'; + 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:2000,char: ",",append:',```',prepend:'```js\n'}}); + return trySend(this.client, msg, {content:sendmesinfo,split:{ maxLength: 4000, char: ",",append: ',```', prepend: '```js\n' }}); } }; \ No newline at end of file diff --git a/cmds/utility/newquoteotd.js b/cmds/utility/newquoteotd.js index f233301..4019bba 100644 --- a/cmds/utility/newquoteotd.js +++ b/cmds/utility/newquoteotd.js @@ -3,8 +3,7 @@ const commando = require("@iceprod/discord.js-commando"); const { MessageEmbed } = require("discord.js"); const { getChannelMessage, errLog, noPerm, tryReact, trySend, ranLog } = require("../../resources/functions"); -const { database } = require("../../database/mongo"); -const col = database.collection("Guild"); +const colorConf = require(`../../config.json`); module.exports = class newquoteotd extends commando.Command { constructor(client) { @@ -19,26 +18,24 @@ module.exports = class newquoteotd extends commando.Command { } async run(msg, arg) { const args = arg.trim().split(/ +/); - const colorConf = require(`../../config.json`); - const findDoc = await col.findOne({document: msg.guild.id}); - const quoteOTD = findDoc?.["settings"]?.quoteOTD; + const quoteOTD = msg.guild.quoteOTD; const color = colorConf.randomColors; if (!quoteOTD || !quoteOTD.channel) { - return trySend(this.client, msg, `Quote OTD channel not set! Run \`${msg.guild.commandPrefix}quoteotd\` to set one.`); + return trySend(this.client, msg, `Quote OTD channel not set! Run \`${msg.guild.commandPrefix + this.name}\` to set one.`); } if (!args[0]) { return trySend(this.client, msg, 'Provide ``!'); } try { let emb = new MessageEmbed(); - const mes = await getChannelMessage(this.client,msg,args[0],args[1]); + const mes = await getChannelMessage(msg, args[0], args[1]); if (mes) { const author = mes.guild.member(mes.author); let description = mes.content; if (!description.endsWith('.')) { description = description+'.'; } - const thumbnail = mes.author.displayAvatarURL({size:4096,dynamic:true}); + const thumbnail = mes.author.displayAvatarURL({format: "png", size: 4096, dynamic: true}); let name; if (author.displayName) { name = author.displayName; @@ -53,7 +50,7 @@ module.exports = class newquoteotd extends commando.Command { .setColor(color[Math.floor(Math.random()*color.length)]); const sent = await trySend(this.client, quoteOTD.channel, emb); if (sent) { - ranLog(this.client, msg, "New quote: " + sent.content + "\nBy: " + mes.author.tag + ` (${mes.author.id})`); + ranLog(msg, "New quote: " + sent.content + "\nBy: " + mes.author.tag + ` (${mes.author.id})`); tryReact(msg, "a:yesLife:794788847996370945"); } return sent; diff --git a/cmds/utility/quoteotd.js b/cmds/utility/quoteotd.js index 5063d4a..94d616e 100644 --- a/cmds/utility/quoteotd.js +++ b/cmds/utility/quoteotd.js @@ -54,7 +54,7 @@ module.exports = class quoteotd extends commando.Command { } } if (result.length > 0) { - ranLog(this.client, msg, result); + ranLog(msg, result); return trySend(this.client, msg, result); } else { return trySend(this.client, msg, `Provide argument: \`--channel [mention, ID], --text [footer text], --icon [url footer icon]\``); diff --git a/cmds/utility/say.js b/cmds/utility/say.js index a924915..426954a 100644 --- a/cmds/utility/say.js +++ b/cmds/utility/say.js @@ -27,7 +27,7 @@ module.exports = class say extends commando.Command { if (args !== noArgs && msg.channel.guild && msg.member.hasPermission("MANAGE_MESSAGES")) { tryDelete(msg); } - ranLog(this.client, msg, sent.content); + ranLog(msg, sent.content); return sent; } }; \ No newline at end of file diff --git a/cmds/utility/send.js b/cmds/utility/send.js index 6bc4c50..4196d59 100644 --- a/cmds/utility/send.js +++ b/cmds/utility/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 } = require("../../resources/functions"); +const { ranLog, errLog, trySend, tryReact, findChannelRegEx, cleanMentionID, getChannelProchedure } = require("../../resources/functions"); module.exports = class send extends commando.Command { constructor(client) { @@ -20,16 +20,7 @@ module.exports = class send extends commando.Command { } const search = cleanMentionID(comarg[0]), sendTheMes = emoteMessage(this.client, args.slice(comarg[0].length).trim()); - let channel; - if (/^\d{17,19}$/.test(search)) { - channel = msg.guild.channels.cache.get(search); - if (!channel && this.client.owners.includes(msg.author)) { - channel = this.client.channels.cache.get(search); - } - } - if (!channel) { - channel = findChannelRegEx(msg, search, ["category", "voice"])[0]; - } + let channel = getChannelProchedure(msg, search); if (!channel) { return trySend(this.client, msg, "That channel is like your gf. Doesn't exist <:cathmmLife:772716381874946068>"); } @@ -54,7 +45,7 @@ module.exports = class send extends commando.Command { }); collector.on('remove', async r => await msg.reactions.resolve(r).id.remove(r.id)); if (send) { - ranLog(this.client, msg, send.content.slice(0, 1900) + "\n\nSent to: " + `[${send.channel.name}](${send.url}) <#${send.channel.id}> (${send.channel.id})`); + ranLog(msg, send.content.slice(0, 1900) + "\n\nSent to: " + `[${send.channel.name}](${send.url}) <#${send.channel.id}> (${send.channel.id})`); tryReact(msg, 'yeLife:796401669188354090'); } return send; diff --git a/cmds/utility/setfootq.js b/cmds/utility/setfootq.js index 2149c35..8766d65 100644 --- a/cmds/utility/setfootq.js +++ b/cmds/utility/setfootq.js @@ -20,18 +20,20 @@ module.exports = class setfootq extends commando.Command { if (msg.guild ? !msg.guild.member(msg.author).hasPermission("MANAGE_GUILD") : false && !this.client.owners.includes(msg.author)) { return trySend(this.client, msg, 'No lol'); } - const data = msg.guild ? "Guild" : "User"; - const col = database.collection(data); - const doc = msg.guild?.id ?? msg.author.id; - const oldQ = await col.findOne({document: doc}); - col.updateOne({document: doc}, {$set: {"settings.defaultEmbed.footerQuote": args.trim()}, $setOnInsert: { document: msg.guild?.id ?? msg.author.id }}, { upsert: true }, async (e) => { - if (e) { - return errLog(e, msg, this.client); - } - const result = await trySend(this.client, msg, `Changed from \`${oldQ?.["settings"]?.defaultEmbed?.footerQuote}\` to \`${args.trim()}\``); - ranLog(this.client, msg, result.content); + let oldQ = msg.guild?.defaultEmbed ?? msg.author.defaultEmbed; + if (!oldQ) { + oldQ = {}; + } + const newQ = oldQ?.footerQuote; + oldQ.footerQuote = args.trim(); + const r = msg.guild ? msg.guild.setDefaultEmbed(oldQ) : msg.author.setDefaultEmbed(oldQ); + if (r) { + const result = await trySend(this.client, msg, `Changed from \`${newQ?.length > 0 ? newQ : "none"}\` to \`${oldQ.footerQuote?.length > 0 ? oldQ.footerQuote : "none"}\``); + await ranLog(msg, result.content); return result; - }); + } else { + return trySend(this.client, msg, "Somethin's wrong <:WhenLife:773061840351657984>"); + } } catch (e) { return errLog(e, msg, this.client); } diff --git a/cmds/utility/uinfo.js b/cmds/utility/uinfo.js index 984fde0..728cbd8 100644 --- a/cmds/utility/uinfo.js +++ b/cmds/utility/uinfo.js @@ -1,7 +1,7 @@ 'use strict'; const commando = require("@iceprod/discord.js-commando"); -const { ranLog, trySend, cleanMentionID, findMemberRegEx } = require("../../resources/functions"); +const { trySend, cleanMentionID, findMemberRegEx } = require("../../resources/functions"); module.exports = class uinfo extends commando.Command { constructor(client) { @@ -31,15 +31,15 @@ module.exports = class uinfo extends commando.Command { const member = msg.guild.member(profile); let result = ""; if (profile) { - result += 'User: '+profile.tag+'```js\n' + JSON.stringify(profile, null, 2)+'```'; + result += 'User: '+profile.tag+'```js\n' + JSON.stringify(profile, (k, v) => v ?? undefined, 2)+'```'; } if (member) { - result += 'As member: '+member.displayName+'```js\n'+JSON.stringify(member, null, 2)+'```'; + result += 'As member: '+member.displayName+'```js\n'+JSON.stringify(member, (k, v) => v ?? undefined, 2)+'```'; if ((member.displayColor)) { result += 'Display color:```js\n'+member.displayColor+'```'; } } - return trySend(this.client, msg, {content: result, split:{maxLength:2000,char: ",",append:',```',prepend:'```js\n'}}); + return trySend(this.client, msg, { content: result, split:{ maxLength: 4000, char: ",", append: ',```', prepend: '```js\n' }}); } catch (e) { return trySend(this.client, msg, "404 ERROR not found~"); } diff --git a/resources/debug.js b/resources/debug.js index 5e3dd86..3bb7375 100644 --- a/resources/debug.js +++ b/resources/debug.js @@ -1,7 +1,7 @@ 'use strict'; -function timestampAt() { - const date = new Date(), +function timestampAt(client) { + const date = new Date(new Date().valueOf() + (client?.matchTimestamp ? client.matchTimestamp : 0)), string = date.toLocaleTimeString("UTC", {"day": "numeric", "month": "2-digit", "year": "2-digit", "hour12": true}), ampm = string.slice(string.length - 3), miliseconds = date.getUTCMilliseconds(), diff --git a/resources/eventsLogger/guildMemberAdd.js b/resources/eventsLogger/guildMemberAdd.js new file mode 100644 index 0000000..863e79d --- /dev/null +++ b/resources/eventsLogger/guildMemberAdd.js @@ -0,0 +1,25 @@ +'use strict'; + +const { GuildMember } = require("discord.js"); +const { getChannelProchedure, defaultEventLogEmbed, trySend } = require("../functions"); +const getColor = require("../getColor"); + +/** + * Log newly joined Guild Member + * @param {GuildMember} member + * @returns + */ +module.exports = (member) => { + if (member.guild.eventChannels?.joinLeave) { + const log = getChannelProchedure(member, member.guild.eventChannels.joinLeave); + 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) + .setDescription(`<@!${member.id}> (${member.id}) just joined.\nWe have ${member.guild.memberCount} total members now.`); + return trySend(member.client, log, emb); + } +} \ No newline at end of file diff --git a/resources/eventsLogger/guildMemberRemove.js b/resources/eventsLogger/guildMemberRemove.js new file mode 100644 index 0000000..11ba860 --- /dev/null +++ b/resources/eventsLogger/guildMemberRemove.js @@ -0,0 +1,28 @@ +'use strict'; + +const { GuildMember } = require("discord.js"); +const { getChannelProchedure, defaultEventLogEmbed, trySend } = require("../functions"); +const getColor = require("../getColor"); + +/** + * + * @param {GuildMember} member + * @returns + */ +module.exports = (member) => { + if (member.guild.eventChannels?.joinLeave) { + const log = getChannelProchedure(member, member.guild.eventChannels.joinLeave); + if (!log) return; + const days = Math.floor(new Date(new Date().valueOf() + member.client.matchTimestamp - member.joinedAt.valueOf()).valueOf() / 86400000), + emb = defaultEventLogEmbed(member.guild); + emb + .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("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); + } +} \ No newline at end of file diff --git a/resources/eventsLogger/guildMemberUpdate.js b/resources/eventsLogger/guildMemberUpdate.js new file mode 100644 index 0000000..e01a154 --- /dev/null +++ b/resources/eventsLogger/guildMemberUpdate.js @@ -0,0 +1,51 @@ +'use strict'; + +const { GuildMember } = require("discord.js"); +const { defaultEventLogEmbed, getChannelProchedure, trySend } = require("../functions"); +const getColor = require("../getColor"); + +/** + * + * @param {GuildMember} memberold + * @param {GuildMember} membernew + * @returns + */ +module.exports = (memberold, membernew) => { + if (membernew.guild.eventChannels?.memberRole === undefined && membernew.guild.eventChannels?.member === undefined) { + 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}); + }; + return; + } + let log; + const emb = defaultEventLogEmbed(membernew.guild); + emb.setTitle("Profile `" + memberold.user.tag + "` updated") + .setThumbnail(membernew.user.cachedAvatarURL ?? memberold.toJSON().displayAvatarURL) + .setColor(getColor("blue")); + if (membernew.guild.eventChannels?.memberRole) { + log = getChannelProchedure(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]"); + } + 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]"); + } + } + if (membernew.guild.eventChannels?.member && membernew.roles.cache.size === memberold.roles.cache.size) { + log = getChannelProchedure(membernew, membernew.guild.eventChannels.member); + if (membernew.displayName != memberold.displayName) { + emb.addField("Nickname", "Changed from `" + memberold.displayName + "` to `" + membernew.displayName + "`"); + } + if (membernew.user.cachedAvatarURL != membernew.user.displayAvatarURL({format: "png", size: 4096, dynamic: true})) { + emb + .setImage(membernew.user.displayAvatarURL({format: "png", size: 4096, dynamic: true})) + .addField("Avatar", (emb.thumbnail ? "This embed's thumbnail is the user's old avatar.\n" : "") + "The image below is the user's new avatar."); + } + } + 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}); + }; + return trySend(membernew.client, log, emb); +} diff --git a/resources/eventsLogger/message.js b/resources/eventsLogger/message.js new file mode 100644 index 0000000..2217ed4 --- /dev/null +++ b/resources/eventsLogger/message.js @@ -0,0 +1,34 @@ +'use strict'; + +const configFile = require("../../config.json"); +const { trySend, noPerm } = require("../functions"); +const { chatAnswer } = require("../shaChat"); + +function giveNickHeart(msg) { + if (/(? { + if (r) return trySend(msg.client, msg, "YES! <3 <3"); + }) + .catch(e => noPerm(msg)); + } + if (/(dont|don't|no|neve|remove).*(giv|put)?.*(heart|nick).*(nick|heart)/i.test(msg.content) && msg.member.displayName?.endsWith(" <3")) { + return msg.member.setNickname(msg.member.displayName.slice(0, -3)) + .then(r => { + if (r) return trySend(msg.client, msg, "okay <3"); + }) + .catch(e => noPerm(msg)); + } +} + +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()); + } +} + +module.exports = { letsChat, giveNickHeart } \ No newline at end of file diff --git a/resources/eventsLogger/messageDelete.js b/resources/eventsLogger/messageDelete.js new file mode 100644 index 0000000..972c01f --- /dev/null +++ b/resources/eventsLogger/messageDelete.js @@ -0,0 +1,40 @@ +'use strict'; + +const { Message } = require("discord.js"); +const { trySend, defaultEventLogEmbed, getChannelProchedure, splitOnLength } = require("../functions"); +const getColor = require("../getColor"); + +/** + * Log message delete event + * @param {Message} msg + * @returns + */ +module.exports = async (msg) => { + if (msg.partial) return; + const ignored = msg.guild.eventChannels.message.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 (!log || !msg.author) return; + const emb = defaultEventLogEmbed(msg.guild); + emb.setColor(getColor("yellow")) + .setTitle("Message " + msg.id + " deleted") + .setDescription(msg.content.length > 0 ? msg.content : "`[EMPTY]`") + .setAuthor(emb.author.name, msg.author?.displayAvatarURL({format: "png", size: 4096, 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); + 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 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) ? "," : "") + "```"); + } + return trySend(msg.client, log, emb); + } +} diff --git a/resources/eventsLogger/messageUpdate.js b/resources/eventsLogger/messageUpdate.js new file mode 100644 index 0000000..7192da8 --- /dev/null +++ b/resources/eventsLogger/messageUpdate.js @@ -0,0 +1,35 @@ +'use strict'; + +const { Message } = require("discord.js"); +const { trySend, defaultEventLogEmbed, getChannelProchedure } = require("../functions"); +const getColor = require("../getColor"); + +/** + * Log message update + * @param {Message} msgold + * @param {Message} msgnew + * @returns + */ +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; + 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 (!log || !msgnew.author) return; + const emb = defaultEventLogEmbed(msgnew.guild); + emb + .setColor(getColor("blue")) + .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})) + .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); + return trySend(msgnew.client, log, emb); + } +} diff --git a/resources/functions.js b/resources/functions.js index 9407ad7..582e48a 100644 --- a/resources/functions.js +++ b/resources/functions.js @@ -1,6 +1,6 @@ 'use strict'; -const { MessageEmbed, Message, GuildMember, User, Client, GuildChannel, Role, MessageOptions, TextChannel, DMChannel } = require('discord.js'); +const { MessageEmbed, Message, GuildMember, User, Client, 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'); @@ -18,13 +18,13 @@ const { CommandoMessage, CommandoClient } = require('@iceprod/discord.js-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."); + 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) { 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\n'; + sendErr = sendErr + errorMessage+'\n'; inLogChannel = errorMessage+'\n'; } } @@ -39,7 +39,7 @@ async function errLog(theError, msg, client, sendTheError, errorMessage, notify) try { inLogChannel = inLogChannel+'```js\n'+theError.stack+'```'; const sendAt = client.channels.cache.get(defaultErrorLogChannel); - sendAt.send(logThis + inLogChannel.trim() + timestampAt(),{split:true}); + sendAt.send(logThis + inLogChannel.trim() + timestampAt(client),{split:{maxLength:4000,char: "\n",append:'```',prepend:'```js\n'}}); } catch (errmes) { console.error(errmes); } @@ -48,14 +48,13 @@ async function errLog(theError, msg, client, sendTheError, errorMessage, notify) /** * Get message object from the message channel or provided channel - * @param {Client} client - This client (this.client) * @param {Message} msg - Message object (msg) * @param {String} MainID - Message ID | Channel ID | Channel Mention * @param {String} SecondID - Message ID * @returns {Promise} Message object | undefined */ -async function getChannelMessage(client, msg, MainID, SecondID) { - if (!MainID || !(client ?? msg)) { +async function getChannelMessage(msg, MainID, SecondID) { + if (!MainID || !msg) { return; } if (/\//.test(MainID)) { @@ -64,9 +63,9 @@ async function getChannelMessage(client, msg, MainID, SecondID) { MainID = splitURL[splitURL.length-2]; } MainID = cleanMentionID(MainID); - if (SecondID && !/\D/.test(SecondID) && client) { + if (SecondID && !/\D/.test(SecondID)) { try { - const meschannel = client.channels.cache.get(MainID); + const meschannel = msg.client.channels.cache.get(MainID); return meschannel.messages.fetch(SecondID); } catch (theError) { return @@ -87,26 +86,27 @@ function execCB(error, stdout, stderr) { /** * Command usage logger - * @param {CommandoClient} client * @param {CommandoMessage} msg * @param {String} addition */ -async function ranLog(client, msg, addition) { - const channel = client.channels.cache.get(ranLogger); +async function ranLog(msg, addition) { + const channel = msg.client.channels.cache.get(ranLogger), + 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({"size": 4096, "dynamic": true})) + embed.setAuthor(msg.author.tag + ` (${msg.author.id})`, msg.author.displayAvatarURL({format: "png", size: 4096, dynamic: true})) .setURL(msg.url) - .setDescription(addition) - .setFooter(timestampAt(), msg.guild?.iconURL({"size": 4096, "dynamic": true})) - .addField("Guild", `**${msg.guild?.name}** (${msg.guild?.id})`, true) - .addField("Channel", `**${msg.channel?.name}** (${msg.channel.id})`, true) + .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})); + 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(client, channel, {embed: embed}); + trySend(msg.client, channel, {embed: embed}); } /** * Notify when more than one member found when looking in the member list - * @param {Client} client - (this.client) * @param {Message} msg - Message object * @param {GuildMember[]} arr - Test array * @param {String} key - Keyword @@ -114,8 +114,8 @@ async function ranLog(client, msg, addition) { * @param {Boolean} withID - Include user_ID * @returns {String} */ -function multipleMembersFound(client, msg, arr, key, max = 4, withID) { - if (arr.length > 0) { +function multipleMembersFound(msg, arr, key, max = 4, withID) { + if (msg && arr.length > 0) { try { let multipleFound = []; for(const one of arr) { @@ -138,7 +138,7 @@ function multipleMembersFound(client, msg, arr, key, max = 4, withID) { } return `Multiple members found for: **${key}**\`\`\`js\n' ${mes}\`\`\``; } catch (e) { - errLog(e, msg, client); + errLog(e, msg, msg.client); } } else { return ''; @@ -147,7 +147,7 @@ function multipleMembersFound(client, msg, arr, key, max = 4, withID) { /** * Get member object with RegExp - * @param {Message} msg Message object of the guild being searched + * @param {Message | GuildMember} msg Object of the guild being searched * @param {String} name Keyword * @returns {GuildMember[]} Member object found */ @@ -173,24 +173,32 @@ function noPerm(msg) { /** * Send message * @param {CommandoClient} client - (this.client) - * @param {Message | String | TextChannel | DMChannel} msg Message object | channel_ID + * @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) * @returns {Promise} Sent message object */ -function trySend(client, msg, content, adCheck = true) { - if (!client || !msg) { +async function trySend(client, msgOrChannel, content, adCheck = true) { + /*if (content instanceof MessageEmbed) { + let fLength = []; + 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 (client.owners.includes(msg.author)) { + if (typeof msgOrChannel === "string") { + msgOrChannel = client.channels.cache.get(msgOrChannel); + }; + msgOrChannel.channel?.startTyping() || msgOrChannel.startTyping(); + if (client.owners.includes(msgOrChannel.author)) { adCheck = false; if (content.disableMentions) { content.disableMentions = "none"; } } - if (typeof msg === "string") { - msg = client.channels.cache.get(msg); - } if (adCheck) { if (content.content) { content.content = sentAdCheck(content.content); @@ -200,13 +208,23 @@ function trySend(client, msg, content, adCheck = true) { } } } - if (msg instanceof Message) { - return msg.channel.send(content).catch(() => {}); + if (msgOrChannel instanceof Message) { + const ret = await msgOrChannel.channel.send(content).catch(() => { + noPerm(msgOrChannel); + msgOrChannel.channel.stopTyping(); + }); + msgOrChannel.channel.stopTyping(); + return ret; } else { - if (msg instanceof TextChannel || msg instanceof DMChannel) { - return msg.send(content).catch(() => {}); + 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 { - console.error("[TRYSEND] Unknown {msg} type.", msg); + errLog(e, null, client, false, "[TRYSEND] Invalid {msgOrChannel} type.```js\n" + JSON.stringify(msgOrChannel, (k, v) => v ?? undefined, 2) + "```"); } } } @@ -219,7 +237,7 @@ function tryDelete(msg) { if (!msg) { return; } - msg.delete().catch(() => {}); + msg.delete().catch(e => {throw e}); } /** @@ -231,12 +249,12 @@ function tryReact(msg, reaction) { if (!msg || reaction.length === 0) { return; } - msg.react(reaction).catch(() => {}); + msg.react(reaction).catch(e => {throw e}); } /** - * Check a message sent by client for ads - * @param {String} content - Sent message object (await msg.channel.send("discord.gg/banana")) + * Check message's content for ads + * @param {String} content - Content to check */ function sentAdCheck(content) { if (content.length > 5) { @@ -249,7 +267,7 @@ function sentAdCheck(content) { /** * Make default image embed - * @param {Message} msg + * @param {Message | GuildMember} msg * @param {String} image * @param {GuildMember | User} author * @param {String} title @@ -258,13 +276,13 @@ function sentAdCheck(content) { */ 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(() => {}); + 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)]) + .setColor(msg.guild ? getColor(msg.member?.displayColor) : randomColors[Math.floor(Math.random() * randomColors.length)]) .setFooter(footerQuote); } @@ -295,7 +313,7 @@ function cleanMentionID(key) { /** * Get channel object wit RegExp - * @param {Message} msg Message object of the guild being searched + * @param {Message | GuildMember} msg Object of the guild being searched * @param {String} name Keyword * @param {ChannelType[]} exclude Exclude channel type * @returns {GuildChannel[]} Channels object found @@ -313,7 +331,7 @@ function findChannelRegEx(msg, name, exclude) { /** * Get role object with RegExp - * @param {Message} msg Message object of the guild being searched + * @param {Message | GuildMember} msg Object of the guild being searched * @param {String} name Keyword * @returns {Role[]} Roles object found */ @@ -324,7 +342,6 @@ function findRoleRegEx(msg, name) { /** * Notify when more than one channel found when looking in the channel list - * @param {Client} client - (this.client) * @param {Message} msg - Message object * @param {GuildChannel[]} arr - Test array * @param {String} key - Keyword @@ -332,7 +349,7 @@ function findRoleRegEx(msg, name) { * @param {Boolean} withID - Include channel_ID * @returns {String} */ -function multipleChannelsFound(client, msg, arr, key, max = 4, withID) { +function multipleChannelsFound(msg, arr, key, max = 4, withID) { if (arr.length > 0) { try { let multipleFound = []; @@ -355,7 +372,7 @@ function multipleChannelsFound(client, msg, arr, key, max = 4, withID) { } return `Multiple channels found for: **${key}**\`\`\`js\n' ${mes}\`\`\``; } catch (e) { - errLog(e, msg, client); + errLog(e, msg, msg.client); } } else { return ''; @@ -364,7 +381,6 @@ function multipleChannelsFound(client, msg, arr, key, max = 4, withID) { /** * Notify when more than one role found when looking in the role list - * @param {Client} client - (this.client) * @param {Message} msg - Message object * @param {Role[]} arr - Test array * @param {String} key - Keyword @@ -372,7 +388,7 @@ function multipleChannelsFound(client, msg, arr, key, max = 4, withID) { * @param {Boolean} withID - Include role_ID * @returns {String} */ - function multipleRolesFound(client, msg, arr, key, max = 4, withID) { + function multipleRolesFound(msg, arr, key, max = 4, withID) { if (arr.length > 0) { try { let multipleFound = []; @@ -395,7 +411,7 @@ function multipleChannelsFound(client, msg, arr, key, max = 4, withID) { } return `Multiple roles found for: **${key}**\`\`\`js\n' ${mes}\`\`\``; } catch (e) { - errLog(e, msg, client); + errLog(e, msg, msg.client); } } else { return ''; @@ -403,13 +419,12 @@ function multipleChannelsFound(client, msg, arr, key, max = 4, withID) { } /** - * Standard - * @param {Client} client this.client + * Standard * @param {Message} msg - Message object * @param {String} key - Channel ID | Mention | Name - * @returns + * @returns {GuildChannel | Channel} Channel object */ -function getChannelProchedure(client, msg, key) { +function getChannelProchedure(msg, key) { if (key.length === 0) { return; } @@ -419,23 +434,68 @@ function getChannelProchedure(client, msg, key) { } let channel; if (/^\d{17,19}$/.test(search)) { - channel = msg.guild.channels.cache.get(search); - if (!channel && client.owners.includes(msg.author)) { - channel = client.channels.cache.get(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 = findChannelRegEx(msg, search, ["category", "voice"])?.[0]; } return channel; } +/** + * Compare 2 different timestamp + * @param {Number} compare - Number to compare + * @returns {Number} Result + */ +function getUTCComparison(compare) { + return compare - new Date().valueOf(); +} +/** + * Make guild's event log embed with author and footer + * @param {Guild} guild + * @returns {MessageEmbed} + */ +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)); +} + +/** + * Split on Length + * @param {Array} arr + * @param {Number} maxLength - Max character length per split + * @param {String} joiner + * @returns {Array} + */ +function splitOnLength(arr, maxLength, joiner = "\n") { + let toField = [], i = 0, pushed = 0; + for (const res of arr) { + if (arr[pushed] && ((toField[i] ? toField[i].join(joiner) : "") + joiner + arr[pushed]).length > maxLength) { + i++; + } else { + pushed++; + } + if (!toField[i] || toField[i].length === 0) { + toField[i] = []; + } + toField[i].push(res); + if (!arr[pushed]) { + break; + } + } + return toField; +} module.exports = { - cleanMentionID, + cleanMentionID, defaultEventLogEmbed, multipleMembersFound, multipleRolesFound, multipleChannelsFound, findMemberRegEx, findChannelRegEx, findRoleRegEx, getChannelMessage, errLog, - execCB, ranLog, noPerm, + execCB, ranLog, noPerm, getUTCComparison, trySend, tryDelete, tryReact, - sentAdCheck, defaultImageEmbed, getChannelProchedure + sentAdCheck, defaultImageEmbed, getChannelProchedure, + splitOnLength } \ No newline at end of file diff --git a/resources/structures.js b/resources/structures.js index 6ef66db..487be3b 100644 --- a/resources/structures.js +++ b/resources/structures.js @@ -16,7 +16,7 @@ Structures.extend("Guild", g => { 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; @@ -42,19 +42,15 @@ Structures.extend("Guild", g => { } } } - if (found.length > 0) { - return found; - } - } else { - return; } + return found; } catch (e) { } } async addInfraction(add) { try { const r = await database.collection("Guild").findOne({ document: this.id }); this.infractions = r?.moderation?.infractions; - const ret = database.collection("Guild").updateOne({document: this.id}, {$push:{"moderation.infractions":add}}, (e) => { + const ret = await 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; @@ -62,24 +58,32 @@ Structures.extend("Guild", g => { return ret; } catch (e) { } } - setEventChannels(set) { - const ret = database.collection("Guild").updateOne({document: this.id}, {$set: {"settings.eventChannels": set}}, {upsert: true}, (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) => { + 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) => { if (e) return errLog(e, null, this.client); this.eventChannels = set; return true; }); return ret; } - setDefaultEmbed(set) { - const ret = database.collection("Guild").updateOne({document: this.id}, {$set:{"settings.defaultEmbed": set}}, {upsert: true}, (e) => { + async setDefaultEmbed(set) { + const ret = await 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; } - setModerationSettings(set) { - const ret = database.collection("Guild").updateOne({document:this.id}, {$set:{"moderation.settings": set}}, {upsert: true}, (e) => { + async setModerationSettings(set) { + const ret = await 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; @@ -100,12 +104,13 @@ Structures.extend("User", u => { 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; + this.cachedAvatarURL = this.displayAvatarURL({format: "png", size: 4096, dynamic: true}); return this.dbLoaded = true; }); return ret; } - setDefaultEmbed(set) { - const ret = database.collection("User").updateOne({document: this.id}, {$set:{"settings.defaultEmbed": set}}, {upsert: true}, (e) => { + async setDefaultEmbed(set) { + const ret = await 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;