From d1b9a2c0dd6f0d2565bf632388dc669fb61004bf Mon Sep 17 00:00:00 2001 From: Neko-Life Date: Wed, 4 Aug 2021 00:20:50 +0700 Subject: [PATCH] too lazy to write desc --- Main.js | 5 + cmds/moderation/ban.js | 119 ++++++++++---------- cmds/moderation/eventlog.js | 12 +- cmds/moderation/mute.js | 17 +-- cmds/moderation/src/createSchedule.js | 1 + cmds/moderation/unban.js | 48 ++++++++ cmds/moderation/unmute.js | 18 ++- cmds/utility/perms.js | 3 +- resources/eventsLogger/guildBanRemove.js | 32 ++++++ resources/eventsLogger/guildMemberAdd.js | 8 +- resources/eventsLogger/guildMemberRemove.js | 10 +- resources/eventsLogger/messageUpdate.js | 2 +- resources/structures.js | 52 ++++++--- 13 files changed, 220 insertions(+), 107 deletions(-) create mode 100644 cmds/moderation/unban.js create mode 100644 resources/eventsLogger/guildBanRemove.js diff --git a/Main.js b/Main.js index 3ccc6d7..1850f78 100644 --- a/Main.js +++ b/Main.js @@ -107,6 +107,10 @@ client.on("guildBanAdd", async (GUILD, USER) => { lgr.guildBanAdd(GUILD, USER); }); +client.on("guildBanRemove", async (GUILD, USER) => { + lgr.guildBanRemove(GUILD, USER); +}) + client.on("messageDelete", async (msg) => { if (msg.author && !msg.author.DB) await msg.author.dbLoad(); if (msg.guild) { @@ -186,6 +190,7 @@ client.on("shardError", async (e, shard) => { client.on("commandRun", async (c, u, msg) => { if (!msg.author.DB) await msg.author.dbLoad(); + if (msg.member) if (!msg.member.DB) await msg.member.dbLoad(); if (msg.guild && !msg.guild.DB) await msg.guild.dbLoad(); }); diff --git a/cmds/moderation/ban.js b/cmds/moderation/ban.js index 08d52a4..edb7d0e 100644 --- a/cmds/moderation/ban.js +++ b/cmds/moderation/ban.js @@ -17,9 +17,7 @@ module.exports = class ban extends commando.Command { description: "Ban pesky troll and toxic members", guildOnly: true, userPermissions: ["BAN_MEMBERS"], - clientPermissions: ["BAN_MEMBERS"], - details: "Args: `user_[name|mention|ID] -- [reason] -- [duration] [--d [number of days to delete messages of the user to ban]]`", - examples: ["some user name, some user tag -- 10d76y8m99mo6h70w -- sending unsolicited cakes in DM --d 5"] + clientPermissions: ["BAN_MEMBERS"] }); } @@ -29,23 +27,24 @@ module.exports = class ban extends commando.Command { * @returns */ async run(msg, arg) { + if (!arg) return trySend(msg.client, msg, + "Args: `user_[name|mention|ID] -- [reason] -- [duration] [--d [number of days to delete messages of the user to ban]]`. Separate `user` with `,`. Example:" + + `\`\`\`js\n${msg.guild.commandPrefix + this.name + } 301859887724363796, Your father, #2341, @Ren Nakamura -- 10d76y8m99mo6h70w -- sending unsolicited cakes in DM --d 5\`\`\``); if (!msg.guild.DB) await msg.guild.dbLoad(); const args = parseDoubleDash(arg), target = parseComa(args?.shift()); let reason = "No reason provided", pDuration = {}, execTarget = [], resultMsg = "", daysToDeleteMessages = 0; - - if (!target || target.length < 1) return trySend(msg.client, msg, this.details); else { - const ET = await targetUser(msg, target); - execTarget = ET.targetUser; - resultMsg = ET.resultMsg; - } + const ET = await targetUser(msg, target); + execTarget = ET.targetUser; + resultMsg = ET.resultMsg; if (args?.[1]) { for (const ARG of args) { if (ARG === "--" || ARG.trim().length < 1) continue; if (ARG.startsWith("d ")) { const U = ARG.slice(2).trim(); - if (U.length > 0 && !/\D/.test(U)) daysToDeleteMessages = parseInt(U, 10); else return trySend(msg.client, msg, "Invalid number of days to delete messages!"); + if (U.length && !/\D/.test(U)) daysToDeleteMessages = parseInt(U, 10); else return trySend(msg.client, msg, "Invalid number of days to delete messages!"); continue; } else if (CHECK_FOR_DURATION_REGEXP.test(ARG.trim())) @@ -54,59 +53,57 @@ module.exports = class ban extends commando.Command { } if (!pDuration.invoked) pDuration.invoked = DateTime.fromJSDate(msg.editedAt || msg.createdAt); + if (!execTarget?.length) if (!resultMsg.length) return; else return trySend(msg.client, msg, resultMsg); - if (execTarget.length > 0) { - /** - * @type {User} - */ - for (const U of execTarget) { - const INFRACTION = createInfraction(msg, execTarget, "ban", reason), - data = { - duration: pDuration, - infraction: INFRACTION.infraction, - moderator: msg.member - }; - let banned = [], already = [], cant = []; - try { - await U.ban(msg.guild, data, { days: daysToDeleteMessages, reason: reason }); - banned.push(U.id); - } catch (e) { - errLog(e, msg, msg.client, true, "", true); - if (/Missing Permissions|someone with higher position/.test(e.message)) cant.push(U.id); - } - - INFRACTION.executed = banned; - INFRACTION.aborted = already; - INFRACTION.failed = cant; - - - const emb = defaultEventLogEmbed(msg.guild) - .setTitle("Infraction #" + INFRACTION.infraction) - .setDescription(reason); - - if (banned.length > 0) { - let bannedStr = "", bannedArr = []; - await msg.guild.addInfraction(INFRACTION); - for (const U of banned) { - const tU = "<@" + U + ">, "; - if ((bannedStr + tU).length < 1000) bannedStr += tU; else bannedArr.push(U); - } - bannedStr = bannedStr.slice(0, -2); - - if (bannedArr.length > 0) bannedStr += ` and ${bannedArr.length} more...`; - if (already.length > 0) emb.addField("Already banned", "<@" + already.join(">, <@") + ">\n\nDuration updated for these users"); - - emb.addField("Banned", bannedStr || "`[NONE]`") - .addField("At", defaultDateFormat(pDuration.invoked), true) - .addField("Until", pDuration.until ? defaultDateFormat(pDuration.until) : "Never", true) - } - emb.addField("For", pDuration.duration?.strings.join(" ") || "Indefinite"); - - if (cant.length > 0) emb.addField("Can't ban", "<@" + cant.join(">, <@") + ">\n\n**You can't ban someone with higher position than you <:nekokekLife:852865942530949160>**") - - return trySend(msg.client, msg, { content: resultMsg, embed: emb }); + /** + * @type {User} + */ + for (const U of execTarget) { + const INFRACTION = createInfraction(msg, execTarget, "ban", reason), + data = { + duration: pDuration, + infraction: INFRACTION.infraction, + moderator: msg.member + }; + let banned = [], already = [], cant = []; + try { + await U.ban(msg.guild, data, { days: daysToDeleteMessages, reason: reason }); + banned.push(U.id); + } catch (e) { + if (/Missing Permissions|someone with higher position/.test(e.message)) cant.push(U.id); } - return trySend(msg.client, msg, resultMsg); + + INFRACTION.executed = banned; + INFRACTION.aborted = already; + INFRACTION.failed = cant; + + + const emb = defaultEventLogEmbed(msg.guild) + .setTitle("Infraction #" + INFRACTION.infraction) + .setDescription(reason); + + if (banned.length) { + let bannedStr = "", bannedArr = []; + await msg.guild.addInfraction(INFRACTION); + for (const U of banned) { + const tU = "<@" + U + ">, "; + if ((bannedStr + tU).length < 1000) bannedStr += tU; else bannedArr.push(U); + } + bannedStr = bannedStr.slice(0, -2); + + if (bannedArr.length) bannedStr += ` and ${bannedArr.length} more...`; + if (already.length) emb.addField("Already banned", "<@" + already.join(">, <@") + ">\n\nDuration updated for these users"); + + emb.addField("Banned", bannedStr || "`[NONE]`") + .addField("At", defaultDateFormat(pDuration.invoked), true) + .addField("Until", pDuration.until ? defaultDateFormat(pDuration.until) : "Never", true) + } + emb.addField("For", pDuration.duration?.strings.join(" ") || "Indefinite"); + + if (cant.length) emb.addField("Can't ban", "<@" + cant.join(">, <@") + ">\n\n**You can't ban someone with higher position than you <:nekokekLife:852865942530949160>**") + + return trySend(msg.client, msg, { content: resultMsg, embed: emb }); } + return trySend(msg.client, msg, resultMsg); } } \ No newline at end of file diff --git a/cmds/moderation/eventlog.js b/cmds/moderation/eventlog.js index 84e5df4..0cfc6fe 100644 --- a/cmds/moderation/eventlog.js +++ b/cmds/moderation/eventlog.js @@ -77,12 +77,12 @@ module.exports = class eventlog extends commando.Command { ignore: [] }; else { const mesArgs = parseDash(args.slice("e ").trim()); - if (mesArgs.length > 0 && /(? 0) { + if (ignoreArgs.length) { for (const ign of ignoreArgs) { if (ign.length === 0) { continue; @@ -122,12 +122,12 @@ module.exports = class eventlog extends commando.Command { } } else { const mesArgs = parseDash(args.slice("d ").trim()); - if (mesArgs.length > 0 && /(? 0) { + if (ignoreArgs.length) { for (const ign of ignoreArgs) { if (ign.length === 0) { continue; @@ -241,10 +241,10 @@ module.exports = class eventlog extends commando.Command { async function resultEmbed(the) { const emb = defaultImageEmbed(msg, null, "Event Log Channels Configuration") .setDescription("`--h` for help") - .addField(`Message Edit`, eventChannels?.mesEd?.channel ? `<#${eventChannels?.mesEd.channel}>\n**Ignores:** ${eventChannels?.mesEd?.ignore?.length > 0 ? + .addField(`Message Edit`, eventChannels?.mesEd?.channel ? `<#${eventChannels?.mesEd.channel}>\n**Ignores:** ${eventChannels?.mesEd?.ignore?.length ? "<#" + eventChannels?.mesEd.ignore.join(">, <#") + ">" : "None"}` : "Not set", true) - .addField(`Message Delete`, eventChannels?.mesDel?.channel ? `<#${eventChannels?.mesDel.channel}>\n**Ignores:** ${eventChannels?.mesDel?.ignore?.length > 0 ? + .addField(`Message Delete`, eventChannels?.mesDel?.channel ? `<#${eventChannels?.mesDel.channel}>\n**Ignores:** ${eventChannels?.mesDel?.ignore?.length ? "<#" + eventChannels?.mesDel.ignore.join(">, <#") + ">" : "None"}` : "Not set", true) .addField(`Member Join`, eventChannels?.join ? `<#${eventChannels.join}>` : "Not set", true) diff --git a/cmds/moderation/mute.js b/cmds/moderation/mute.js index 65b288a..49654c8 100644 --- a/cmds/moderation/mute.js +++ b/cmds/moderation/mute.js @@ -103,13 +103,16 @@ module.exports = class mute extends commando.Command { duration.duration = fn.intervalToDuration(duration.interval); } - if (mentions?.length > 0) { + if (mentions?.length) { const FR = await targetUser(msg, mentions, targetUsers, resultMsg); targetUsers = FR.targetUser; resultMsg = FR.resultMsg; - } else return trySend(this.client, msg, "Args: `<[user_[mention|ID|name]]> -- [reason] -- [duration]`. Use `,` to provide multiple user. `--s` to view settings.\nExample:```js\n" + `${msg.guild.commandPrefix + this.name} 580703409934696449, @Shasha#1234, ur mom,#6969,^yuck\\s(ur)?\\s.{5}#\\d+69$--69y69mo69w420d420h420m420s -- Saying "joe"\`\`\``); + } else return trySend(this.client, msg, "Args: `<[user_[mention|ID|name]]> -- [reason] -- [duration]`. " + + "Separate `user` with `,`. `--s` to view settings.\nExample:```js\n" + + `${msg.guild.commandPrefix + this.name} 580703409934696449, @Shasha#1234, ` + + `ur mom,#6969,^yuck\\s(ur)?\\s.{5}#\\d+69$ -- 69y69mo69w420d420h420m420s -- Saying "joe"\`\`\``); - if (targetUsers.length > 0) { + if (targetUsers.length) { let muted = [], cant = [], already = []; const infractionToDoc = createInfraction(msg, targetUsers, "mute", reason); @@ -131,7 +134,7 @@ module.exports = class mute extends commando.Command { const emb = defaultEventLogEmbed(msg.guild) .setTitle("Infraction #" + infractionToDoc.infraction) .setDescription(reason); - if (muted.length > 0) { + if (muted.length) { let mutedStr = "", mutedArr = []; await msg.guild.addInfraction(infractionToDoc); for (const U of muted) { @@ -140,8 +143,8 @@ module.exports = class mute extends commando.Command { } mutedStr = mutedStr.slice(0, -2); - if (mutedArr.length > 0) mutedStr += ` and ${mutedArr.length} more...`; - if (already.length > 0) emb.addField("Already muted", "<@" + already.join(">, <@") + ">\n\nDuration updated for these users"); + if (mutedArr.length) mutedStr += ` and ${mutedArr.length} more...`; + if (already.length) emb.addField("Already muted", "<@" + already.join(">, <@") + ">\n\nDuration updated for these users"); emb.addField("Muted", mutedStr || "`[NONE]`") .addField("At", defaultDateFormat(duration.invoked), true) @@ -149,7 +152,7 @@ module.exports = class mute extends commando.Command { } emb.addField("For", duration.duration?.strings.join(" ") || "Indefinite"); - if (cant.length > 0) emb.addField("Can't mute", "<@" + cant.join(">, <@") + ">\n\n**You can't mute someone with higher position than you <:nekokekLife:852865942530949160>**"); + if (cant.length) emb.addField("Can't mute", "<@" + cant.join(">, <@") + ">\n\n**You can't mute someone with higher position than you <:nekokekLife:852865942530949160>**"); return trySend(msg.client, msg, { content: resultMsg, embed: emb }); } diff --git a/cmds/moderation/src/createSchedule.js b/cmds/moderation/src/createSchedule.js index 46ddc44..d085f47 100644 --- a/cmds/moderation/src/createSchedule.js +++ b/cmds/moderation/src/createSchedule.js @@ -55,6 +55,7 @@ async function init(client) { await jobLoad(); jobManager = scheduler(client, jobs); + module.exports.jobManager = jobManager; console.log("SCHEDULER INITIALIZED"); return jobStart(); diff --git a/cmds/moderation/unban.js b/cmds/moderation/unban.js new file mode 100644 index 0000000..e6cbc34 --- /dev/null +++ b/cmds/moderation/unban.js @@ -0,0 +1,48 @@ +const commando = require("@iceprod/discord.js-commando"); +const { parseDoubleDash, parseComa, trySend, defaultEventLogEmbed, errLog } = require("../../resources/functions"); +const targetUser = require("./src/targetUser"); + +module.exports = class unbanCmd extends commando.Command { + constructor(client) { + super(client, { + name: "unban", + memberName: "unban", + group: "moderation", + description: "Unban user from your server", + userPermissions: ["ADMINISTRATOR"], + clientPermissions: ["ADMINISTRATOR"] + }); + } + + async run(msg, arg) { + if (!arg) return trySend(msg.client, msg, "Provide `user_ID` to unban. Separate `user` with `,`. Example:```js\n" + + `${msg.guild.commandPrefix + this.name} 757453290714824844, 706039105540194314, 198558078508072960 ` + + `-- sent me some nice materials for tonight\`\`\``); + const args = parseDoubleDash(arg), + target = parseComa(args?.shift()); + let reason = "No reason provided", execTarget = [], resultMsg = ""; + if (args[1]?.trim().length) reason = args[1].trim(); + const F = await targetUser(msg, target); + execTarget = F.targetUser; + resultMsg = F.resultMsg; + if (!execTarget.length) return trySend(msg.client, msg, resultMsg); + + let success = [], cant = []; + for (const T of execTarget) { + try { + await T.unban(msg.guild, msg.member, reason); + success.push(T.id); + } catch (e) { + errLog(e, msg, msg.client, true, "", true); + cant.push(T.id); + } + + const emb = defaultEventLogEmbed(msg.guild); + if (cant.length) emb.addField("Can't unban", "<@" + cant.join(">, <@") + ">"); + emb.setDescription(reason) + .setTitle("Unban") + .addField("Unbanned", success.length ? "<@" + success.join(">, <@") + ">" : "`[NONE]`"); + return trySend(msg.client, msg, emb); + } + } +}; \ No newline at end of file diff --git a/cmds/moderation/unmute.js b/cmds/moderation/unmute.js index 27b725a..61ce2bb 100644 --- a/cmds/moderation/unmute.js +++ b/cmds/moderation/unmute.js @@ -11,7 +11,6 @@ module.exports = class unmute extends commando.Command { memberName: "unmute", group: "moderation", description: "Mute.", - details: "Args: `user_[mention|name|ID] -- [reason]`", guildOnly: true, userPermissions: ['MANAGE_ROLES'], clientPermissions: ['MANAGE_ROLES'] @@ -21,14 +20,13 @@ module.exports = class unmute extends commando.Command { async run(msg, arg) { if (!msg.guild.DB) await msg.guild.dbLoad(); msg.channel.startTyping(); - if (!arg) return trySend(msg.client, msg, this.details); + if (!arg) return trySend(msg.client, msg, "Provide `user_ID` to unmute. Separate `user` with `,`. Example:```js\n" + + `${msg.guild.commandPrefix + this.name} uwu#123, 198558078508072960, elite guitarist -- They got nice manners irl\`\`\``); const args = parseDoubleDash(arg), mentions = parseComa(args.shift()); let reason = "No reason provided", targetUsers = [], resultMsg = ""; - if (args?.length > 0) { - for (const ARG of args) if (!ARG || ARG === "--" || ARG.trim().length === 0) continue; else reason = ARG.trim(); - } - if (mentions?.length > 0) { + if (args[1]?.trim().length) reason = args[1].trim(); + if (mentions?.length) { const FR = await targetUser(msg, mentions, targetUsers, resultMsg); targetUsers = FR.targetUser; resultMsg = FR.resultMsg; @@ -51,12 +49,12 @@ module.exports = class unmute extends commando.Command { } const emb = defaultEventLogEmbed(msg.guild); - if (notMuted.length > 0) emb.addField("Wasn't muted", "<@" + notMuted.join(">, <@") + ">"); + if (notMuted.length) emb.addField("Wasn't muted", "<@" + notMuted.join(">, <@") + ">"); emb.setTitle("Unmute") - .setDescription("**Reason**\n" + reason) - .addField("Unmuted", (success.length > 0 ? "<@" + success.join(">, <@") + ">" : "`[NONE]`")); - if (cant.length > 0) emb.addField("Can't unmute", "<@" + cant.join(">, <@") + ">"); + .setDescription(reason) + .addField("Unmuted", (success.length ? "<@" + success.join(">, <@") + ">" : "`[NONE]`")); + if (cant.length) emb.addField("Can't unmute", "<@" + cant.join(">, <@") + ">"); return trySend(msg.client, msg, { content: resultMsg, embed: emb }); } } \ No newline at end of file diff --git a/cmds/utility/perms.js b/cmds/utility/perms.js index 20549f7..c2cf7c8 100644 --- a/cmds/utility/perms.js +++ b/cmds/utility/perms.js @@ -66,7 +66,6 @@ module.exports = class perms extends commando.Command { } const title = `Permissions for: \`${member.user.tag}\``; mes += `**Default:**\`\`\`js\n`; - if (member.isAdmin) mes += "'ADMINISTRATOR', "; if (res.length > 0) { mes += `${res.join(", ")}\`\`\``; } else { @@ -76,7 +75,7 @@ module.exports = class perms extends commando.Command { if (chanres.length > 0) { emb.addField(`In channel: \`${channel.name}\``, `\`\`\`js\n${chanres.join(", ")}\`\`\``); } - emb.setDescription(mes) + emb.setDescription(mes.replace("ADMINISTRATOR", "'ADMINISTRATOR'")) .setColor(getColor(member.displayColor)) .setThumbnail(member.user.displayAvatarURL({ size: 4096, format: "png", dynamic: true })); return trySend(this.client, msg, emb); diff --git a/resources/eventsLogger/guildBanRemove.js b/resources/eventsLogger/guildBanRemove.js new file mode 100644 index 0000000..315c736 --- /dev/null +++ b/resources/eventsLogger/guildBanRemove.js @@ -0,0 +1,32 @@ +'use strict'; + +const { Guild, User } = require("discord.js"); +const { getChannel, defaultEventLogEmbed, trySend } = require("../functions"); +const getColor = require("../getColor"); + +/** + * @param {Guild} GUILD + * @param {User} USER + * @returns + */ +module.exports = async (GUILD, USER) => { + if (GUILD.DB.eventChannels?.unban) { + if (USER.partial) USER = await USER.fetch(); + const log = getChannel(GUILD, GUILD.DB.eventChannels.unban); + if (!log) return; + const emb = defaultEventLogEmbed(GUILD); + let audit; + if (GUILD.member(GUILD.client.user).hasPermission("VIEW_AUDIT_LOG")) { + const the = (await GUILD.fetchAuditLogs({ limit: 1, type: "MEMBER_BAN_REMOVE" })).entries.first(); + console.log(the); + if (the.target.id === USER.id) audit = the; + emb.setDescription(audit?.reason || "No reason provided"); + } else emb.setDescription("Unknown reason"); + + emb.setTitle(`\`${USER.tag}\` unbanned` + (audit?.executor ? ` by \`${audit.executor.tag}\`` : "")) + .setColor(getColor("red")) + .setThumbnail(USER.displayAvatarURL({ size: 4096, format: "png", dynamic: true })) + .addField("User", `<@${USER.id}>\n(${USER.id})`); + return trySend(GUILD.client, log, emb); + } +} \ No newline at end of file diff --git a/resources/eventsLogger/guildMemberAdd.js b/resources/eventsLogger/guildMemberAdd.js index 651ed7c..d266ef5 100644 --- a/resources/eventsLogger/guildMemberAdd.js +++ b/resources/eventsLogger/guildMemberAdd.js @@ -11,7 +11,13 @@ const { GuildMember } = require("discord.js"), * @param {GuildMember} member * @returns */ -module.exports = (member) => { +module.exports = async (member) => { + if (!member.DB) await member.dbLoad(); + if (member.DB.leaveRoles?.length && member.guild.member(member.client.user).hasPermission("MANAGE_ROLES")) { + await member.roles.add(member.DB.leaveRoles, "Automatic roles recovery").then(() => console.log("AUTO ROLES RECOVERY:", + member.user.tag, member.guild.name)).catch(() => { }); + await member.setDb("leaveRoles", []); + } if (member.guild.DB.eventChannels?.join) { const log = getChannel(member, member.guild.DB.eventChannels.join); if (!log) return; diff --git a/resources/eventsLogger/guildMemberRemove.js b/resources/eventsLogger/guildMemberRemove.js index 9ad4715..c8cab61 100644 --- a/resources/eventsLogger/guildMemberRemove.js +++ b/resources/eventsLogger/guildMemberRemove.js @@ -2,7 +2,7 @@ const { GuildMember } = require("discord.js"); const { DateTime, Interval, Settings } = require("luxon"); -const { DT_PRINT_FORMAT, intervalToDuration } = require("../../cmds/moderation/src/duration"); +const { intervalToDuration } = require("../../cmds/moderation/src/duration"); const { getChannel, defaultEventLogEmbed, trySend, splitOnLength, defaultDateFormat } = require("../functions"); const getColor = require("../getColor"); Settings.defaultZone = "utc"; @@ -11,15 +11,16 @@ Settings.defaultZone = "utc"; * @param {GuildMember} member * @returns */ -module.exports = (member) => { +module.exports = async (member) => { + const RO = member.roles.cache.sort((a, b) => b.position - a.position).map(r => r.id).slice(0, -1); if (member.guild.DB.eventChannels?.leave) { const log = getChannel(member, member.guild.DB.eventChannels.leave); if (!log) return; const emb = defaultEventLogEmbed(member.guild), - RO = member.roles.cache.sort((a, b) => b.position - a.position).map(r => r.id).slice(0, -1), RU = splitOnLength(RO, 1010, ">, <@&"), LE = DateTime.fromJSDate(member.joinedAt), INT = Interval.fromDateTimes(LE, DateTime.now()); + emb .setTitle("`" + member.user.tag + "` left") .setThumbnail(member.user.displayAvatarURL({ format: "png", size: 4096, dynamic: true })) @@ -28,8 +29,9 @@ module.exports = (member) => { .addField("Joined", defaultDateFormat(member.joinedAt) + `\n(${intervalToDuration(INT).strings.join(" ")} ago)`) .setDescription(`<@!${member.id}> (${member.id}) just left.\nWe have ${member.guild.memberCount} total members now.`); for (const U of RU) { - emb.addField(emb.fields.length === 2 ? "Roles" : "​", U.length > 0 ? "<@&" + U.join(">, <@&") + ">" : "`[NONE]`"); + emb.addField(emb.fields.length === 2 ? "Roles" : "​", U.length ? "<@&" + U.join(">, <@&") + ">" : "`[NONE]`"); } return trySend(member.client, log, emb); } + await member.setLeaveRoles(RO); } \ No newline at end of file diff --git a/resources/eventsLogger/messageUpdate.js b/resources/eventsLogger/messageUpdate.js index 185945b..6444e57 100644 --- a/resources/eventsLogger/messageUpdate.js +++ b/resources/eventsLogger/messageUpdate.js @@ -25,7 +25,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: 128, dynamic: true })) + .setAuthor(msgnew.guild.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/structures.js b/resources/structures.js index 9231b71..f607af0 100644 --- a/resources/structures.js +++ b/resources/structures.js @@ -33,6 +33,7 @@ Structures.extend("Guild", u => { } r.infractions = infractions; r.timedPunishments = timedPunishments; + console.log("DB LOADED FOR GUILD:", this.name, this.id); return this.DB = r; }); } @@ -129,9 +130,11 @@ Structures.extend("Guild", u => { * @returns {boolean} */ async removeTimedPunishment(userID, type) { - console.log("REMOVE TIMEDPUNISHMENT"); const ret = this.DB.timedPunishments.delete(userID + "/" + type); await this.setDb("timedPunishments", this.DB.timedPunishments); + await require("../cmds/moderation/src/createSchedule").jobManager?.stop([this.id, userID, type].join("/")).catch(() => { }); + await require("../cmds/moderation/src/createSchedule").jobManager?.remove([this.id, userID, type].join("/")).catch(() => { }); + console.log("REMOVED TIMEDPUNISHMENT"); return ret; } } @@ -151,6 +154,7 @@ Structures.extend("User", u => { if (!r.F) r.F = "<:pepewhysobLife:853237646666891274>"; if (!r.cachedAvatarURL) r.cachedAvatarURL = this.displayAvatarURL({ format: "png", size: 4096, dynamic: true }); if (!r.interactions) r.interactions = {}; + console.log("DB LOADED FOR USER:", this.tag, this.id); return this.DB = r; }); } @@ -212,7 +216,7 @@ Structures.extend("User", u => { if (!this.bot) { const emb = defaultEventLogEmbed(guild); emb.setTitle("You have been muted") - .setDescription("**Reason**\n" + reason) + .setDescription(reason || "No reason provided") .addField("At", defaultDateFormat(data.duration.invoked), true) .addField("Until", data.duration.until ? defaultDateFormat(data.duration.until) : "Never", true) .addField("For", data.duration.duration?.strings.join(" ") || "Indefinite"); @@ -245,7 +249,7 @@ Structures.extend("User", u => { const emb = defaultEventLogEmbed(guild); emb.setTitle("You have been unmuted") - .setDescription("**Reason**\n" + reason); + .setDescription(reason || "No reason provided"); this.createDM().then(r => trySend(this.client, r, emb)); } @@ -284,38 +288,46 @@ Structures.extend("User", u => { if (!this.bot) { const emb = defaultEventLogEmbed(guild); emb.setTitle("You have been banned") - .setDescription("**Reason**\n" + option.reason) + .setDescription(option.reason || "No reason provided") .addField("At", defaultDateFormat(data.duration.invoked), true) .addField("Until", data.duration.until ? defaultDateFormat(data.duration.until) : "Never", true) .addField("For", data.duration.duration?.strings.join(" ") || "Indefinite"); await this.createDM().then(r => trySend(this.client, r, emb)); } + let already = false, cant = false; + if (option.days > 7) option.days = 7; await guild.members.ban(this, option); + // .catch(e => { + + // }); + if (data.duration.until) await createSchedule(guild.client, { guildID: guild.id, userID: this.id, type: "ban", until: data.duration.until?.toJSDate() }); const MC = guild.getTimedPunishment(this.id, "ban"), TP = new TimedPunishment({ userID: this.id, duration: data.duration, infraction: data.infraction, type: "ban" }); - if (data.duration.until) await createSchedule(guild.client, { guildID: guild.id, userID: this.id, type: "ban", until: data.duration.until?.toJSDate() }); - - return { set: await guild.setTimedPunishment(TP), existing: MC } + return { set: await guild.setTimedPunishment(TP), existing: MC, already: already, cant: cant } } async unban(guild, moderator, reason) { if (!guild || !(guild instanceof Guild)) throw new TypeError("Guild is: " + guild); const CL = guild.member(this.client.user); if (!moderator.isAdmin || !CL.isAdmin) throw new Error("Missing permissions"); + let already = false, cant = false; await guild.members.unban(this, reason); + // .catch(e => { + + // }); if (!guild.DB) await guild.DB.dbLoad(); if (!this.bot) { const emb = defaultEventLogEmbed(guild); emb.setTitle("You have been unbanned") - .setDescription("**Reason**\n" + reason); + .setDescription(reason || "No reason provided"); this.createDM().then(r => trySend(this.client, r, emb)); } await col.deleteOne({ document: [guild.id, this.id, "ban"].join("/") }).then(() => console.log("SCHEDULE " + [guild.id, this.id, "ban"].join("/") + " DELETED")).catch(e => errLog(e, null, client)); - return guild.removeTimedPunishment(this.id, "ban"); + return { set: await guild.removeTimedPunishment(this.id, "ban"), already: already, cant: cant }; } } }); @@ -375,12 +387,13 @@ Structures.extend("GuildMember", u => { return database.collection("GuildMember").findOne({ document: this.guild.id + "/" + this.id }).then((r, e) => { if (e) return errLog(e, null, this.client); if (!r) r = {}; + console.log("DB LOADED FOR MEMBER:", this.user.tag, this.id, this.guild.name, this.guild.id); return this.DB = r; }); } async setDb(query, set) { - return database.collection("GuildMember").updateOne({ document: this.guild.id + "/" + this.id }, { $set: { [query]: set }, $setOnInsert: { document: this.id } }, + return database.collection("GuildMember").updateOne({ document: this.guild.id + "/" + this.id }, { $set: { [query]: set }, $setOnInsert: { document: this.guild.id + "/" + this.id } }, { upsert: true }).then((r, e) => { if (e) return errLog(e, null, this.client); return this.DB[query] = set; @@ -400,23 +413,23 @@ Structures.extend("GuildMember", u => { if (!this.DB) await this.dbLoad(); if (!data || !data.infraction) throw new Error("Missing infraction id"); if (!this.DB.muted) this.DB.muted = {}; - if (data.saveTakenRoles === undefined) data.saveTakenRoles = !(this.DB.muted.takenRoles?.length > 0); + if (data.saveTakenRoles === undefined) data.saveTakenRoles = !(this.DB.muted.takenRoles?.length); const ROLES = this.roles.cache.filter((r) => !r.managed).map(r => r.id); - if (data.saveTakenRoles && ROLES?.length > 0) { + if (data.saveTakenRoles && ROLES?.length) { console.log("populating takenRoles M"); this.DB.muted.takenRoles = ROLES; } this.DB.muted.muteRole = this.guild.DB.settings.mute.role; try { - if (ROLES?.length > 0) await this.roles.remove(ROLES, reason); + if (ROLES?.length) await this.roles.remove(ROLES, reason); await this.roles.add(this.DB.muted.muteRole, reason); if (!this.DB.muted.takenRoles) this.DB.muted.takenRoles = []; await this.setDb("muted", this.DB.muted); return true; } catch (e) { - if (this.DB.muted.takenRoles?.length > 0) await this.roles.add(this.DB.muted.takenRoles, reason).catch(() => { }); + if (this.DB.muted.takenRoles?.length) await this.roles.add(this.DB.muted.takenRoles, reason).catch(() => { }); if (this.DB.muted.muteRole) await this.roles.remove(this.DB.muted.muteRole, reason).catch(() => { }); console.log("clear takenRoles M"); this.DB.muted.takenRoles = []; @@ -428,7 +441,7 @@ Structures.extend("GuildMember", u => { async unmute(reason) { if (!this.DB) await this.dbLoad(); try { - if (this.DB.muted.takenRoles.length > 0) await this.roles.add(this.DB.muted.takenRoles, reason); + if (this.DB.muted.takenRoles.length) await this.roles.add(this.DB.muted.takenRoles, reason); if (this.DB.muted.muteRole) await this.roles.remove(this.DB.muted.muteRole, reason); console.log("clear takenRoles UM"); this.DB.muted.takenRoles = []; @@ -444,6 +457,15 @@ Structures.extend("GuildMember", u => { * @param {string[]} roles */ async setLeaveRoles(roles = []) { + if (!this.DB) await this.dbLoad(); + const banned = await this.guild.fetchBan(this.user).catch(() => { }); + console.log("BANNED:", banned ? true : false); + if (banned) return; + const kicked = (await this.guild.fetchAuditLogs({ "limit": 1, "type": "MEMBER_KICK" }).catch(() => { }))?.entries?.first(); + if (kicked?.target.id === this.id) { + console.log("KICKED:", true); + return; + } return this.setDb("leaveRoles", roles); }