added ban command

This commit is contained in:
Neko-Life 2021-08-01 15:28:35 +07:00
parent 642a1f6fe6
commit af01df4b07
8 changed files with 111 additions and 54 deletions

View file

@ -1,9 +1,10 @@
'use strict';
const commando = require("@iceprod/discord.js-commando");
const { Message } = require("discord.js");
const { Message, User } = require("discord.js");
const { DateTime } = require("luxon");
const { parseDoubleDash, trySend } = require("../../resources/functions");
const { parseDoubleDash, trySend, errLog, defaultEventLogEmbed, defaultDateFormat, parseComa } = require("../../resources/functions");
const createInfraction = require("./src/createInfraction");
const { duration, CHECK_FOR_DURATION_REGEXP } = require("./src/duration");
const targetUser = require("./src/targetUser");
@ -28,11 +29,12 @@ module.exports = class ban extends commando.Command {
* @returns
*/
async run(msg, arg) {
if (!msg.guild.DB) await msg.guild.dbLoad();
const args = parseDoubleDash(arg),
target = args?.shift();
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.description); else {
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;
@ -54,9 +56,57 @@ module.exports = class ban extends commando.Command {
if (!pDuration.invoked) pDuration.invoked = DateTime.fromJSDate(msg.editedAt || msg.createdAt);
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 });
}
return trySend(msg.client, msg, resultMsg);
}
}
}

View file

@ -239,8 +239,7 @@ module.exports = class eventlog extends commando.Command {
return trySend(this.client, msg, (await resultEmbed(this)).setDescription(report.slice(0, 2048)));
async function resultEmbed(the) {
const emb = defaultImageEmbed(msg, null, "Event Log Channels Configuration");
emb
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 ?
"<#" + eventChannels?.mesEd.ignore.join(">, <#") + ">" : "None"}`

View file

@ -127,22 +127,22 @@ module.exports = class mute extends commando.Command {
infractionToDoc.aborted = already;
infractionToDoc.failed = cant;
if (muted.length > 0) await msg.guild.addInfraction(infractionToDoc);
const emb = defaultEventLogEmbed(msg.guild);
let mutedStr = "", mutedArr = [];
if (muted.length > 0) for (const U of muted) {
const tU = "<@" + U + ">, ";
if ((mutedStr + tU).length < 1000) mutedStr += tU; else mutedArr.push(U);
}
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");
emb.setTitle("Infraction #" + infractionToDoc.infraction)
.setDescription("**Reason**\n" + reason);
const emb = defaultEventLogEmbed(msg.guild)
.setTitle("Infraction #" + infractionToDoc.infraction)
.setDescription(reason);
if (muted.length > 0) {
let mutedStr = "", mutedArr = [];
await msg.guild.addInfraction(infractionToDoc);
for (const U of muted) {
const tU = "<@" + U + ">, ";
if ((mutedStr + tU).length < 1000) mutedStr += tU; else mutedArr.push(U);
}
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");
emb.addField("Muted", mutedStr || "`[NONE]`")
.addField("At", defaultDateFormat(duration.invoked), true)
.addField("Until", duration.until ? defaultDateFormat(duration.until) : "Never", true)

View file

@ -42,11 +42,9 @@ function duration(base, string) {
DURATION_ARGS = string.match(DURATION_REGEXP);
let changed = false;
console.log(DURATION_ARGS, DT_INVOKED.toFormat(DT_PRINT_FORMAT));
for (const value of DURATION_ARGS) {
const val = parseInt(value.match(/[\-]?\d+/)[0], 10);
console.log(val);
if (!val) continue;
if (value.endsWith("h") || value.endsWith("ho")) {
DURATION.hour = DURATION.hour + val;

View file

@ -5,23 +5,24 @@ const { getChannel, defaultEventLogEmbed, trySend } = require("../functions");
const getColor = require("../getColor");
/**
* @param {Guild} GUILD
* @param {User} USER
* @returns
* @param {Guild} GUILD
* @param {User} USER
* @returns
*/
module.exports = async (GUILD, USER) => {
if (GUILD.DB.settings.eventChannels?.ban) {
if (GUILD.DB.eventChannels?.ban) {
if (USER.partial) USER = await USER.fetch();
const log = getChannel(GUILD, GUILD.DB.settings.eventChannels.ban);
const log = getChannel(GUILD, GUILD.DB.eventChannels.ban);
if (!log) return;
const emb = defaultEventLogEmbed(GUILD);
let audit;
if (GUILD.member(GUILD.client.user).hasPermission("VIEW_AUDIT_LOG")) {
audit = (await GUILD.fetchAuditLogs({ limit: 1, type: "MEMBER_BAN_ADD" })).entries.first().executor;
}
const rea = (await GUILD.fetchBan(USER)).reason;
emb.setDescription(rea || "No reason provided")
.setTitle(`\`${USER.tag}\` banned` + (audit ? ` by \`${audit.tag}\`` : ""))
audit = (await GUILD.fetchAuditLogs({ limit: 1, type: "MEMBER_BAN_ADD" })).entries.first();
console.log(audit);
emb.setDescription(audit?.reason || "No reason provided");
} else emb.setDescription("Unknown reason");
emb.setTitle(`\`${USER.tag}\` banned` + (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})`);

View file

@ -21,11 +21,12 @@ module.exports = async (memberold, membernew) => {
const emb = defaultEventLogEmbed(membernew.guild), oldT = memberold.toJSON().displayAvatarURL;
const oldAV = membernew.user.DB.cachedAvatarURL || oldT;
if (oldAV) thumbMes += "This embed's thumbnail is the user's old avatar.\n";
let audit;
let audit, auditPerm;
if (membernew.guild.DB.eventChannels?.memberRole) {
log = getChannel(membernew, membernew.guild.DB.eventChannels.memberRole);
if (membernew.guild.member(membernew.client.user).hasPermission("VIEW_AUDIT_LOG")) {
audit = (await membernew.guild.fetchAuditLogs({ limit: 1, type: "MEMBER_ROLE_UPDATE" })).entries.first().executor;
audit = (await membernew.guild.fetchAuditLogs({ limit: 1, type: "MEMBER_ROLE_UPDATE" })).entries.first();
auditPerm = true;
}
if (membernew.roles.cache.size > memberold.roles.cache.size) {
const use = membernew.roles.cache.difference(memberold.roles.cache).sort((a, b) => b.position - a.position).map(r => r.id);
@ -35,7 +36,7 @@ module.exports = async (memberold, membernew) => {
("<@&" + use.slice(0, 39).join(">, <@&") + ">" + (use.length > 39 ? ` and ${use.slice(39).length} more...` : "")))
.setDescription(`**Old role${use2.length > 2 ? "s" : ""}**\n` + (memberold.roles.cache.size > 1 ? "<@&" +
use2.slice(0, 82).join(">, <@&") + ">" + (use2.length > 82 ? ` and ${use2.slice(82).length} more...` : "") : "`[NONE]`"));
use2.slice(0, 80).join(">, <@&") + ">" + (use2.length > 80 ? ` and ${use2.slice(80).length} more...` : "") : "`[NONE]`"));
}
if (membernew.roles.cache.size < memberold.roles.cache.size) {
const use = memberold.roles.cache.difference(membernew.roles.cache).sort((a, b) => b.position - a.position).map(r => r.id);
@ -45,14 +46,15 @@ module.exports = async (memberold, membernew) => {
("<@&" + use.slice(0, 39).join(">, <@&") + ">" + (use.length > 39 ? ` and ${use.slice(39).length} more...` : "")))
.setDescription(`**Current role${membernew.roles.cache.size > 2 ? "s" : ""}**\n` + (membernew.roles.cache.size > 1 ? "<@&" +
use2.slice(0, 82).join(">, <@&") + ">" + (use2.length > 82 ? ` and ${use2.slice(82).length} more...` : "") : "`[NONE]`"));
use2.slice(0, 80).join(">, <@&") + ">" + (use2.length > 80 ? ` and ${use2.slice(80).length} more...` : "") : "`[NONE]`"));
}
}
if (membernew.guild.DB.eventChannels?.member && membernew.roles.cache.size === memberold.roles.cache.size) {
log = getChannel(membernew, membernew.guild.DB.eventChannels.member);
if (membernew.displayName !== memberold.displayName) {
if (membernew.guild.member(membernew.client.user).hasPermission("VIEW_AUDIT_LOG")) {
audit = (await membernew.guild.fetchAuditLogs({ limit: 1, type: "MEMBER_UPDATE" })).entries.first().executor;
audit = (await membernew.guild.fetchAuditLogs({ limit: 1, type: "MEMBER_UPDATE" })).entries.first();
auditPerm = true;
}
emb.addField("Current Nickname", "`" + membernew.displayName + "`")
.addField("Original Nickname", "`" + memberold.displayName + "`")
@ -66,8 +68,11 @@ module.exports = async (memberold, membernew) => {
}
emb.setAuthor(emb.author.name, NEWAV)
.setTitle("Profile `" + memberold.user.tag + "` updated" +
(audit ? ` by \`${audit.tag}\`` : ""))
(audit?.executor ? ` by \`${audit.executor.tag}\`` : ""))
.setColor(getColor("blue"));
if (auditPerm) {
emb.setDescription((audit?.reason || "No reason provided") + (emb.description ? "\n\n" + emb.description : ""));
} else emb.setDescription("Unknown reason\n\n" + emb.description);
membernew.user.DB.cachedAvatarURL = NEWAV;
membernew.user.setDb("cachedAvatarURL", membernew.user.DB.cachedAvatarURL);
if (!emb.fields || emb.fields.length === 0) return;

View file

@ -20,8 +20,7 @@ module.exports = async (msgold, msgnew) => {
if (msgnew.guild.DB.eventChannels.mesEd?.channel !== msgnew.channel.id && ignored === false || check) {
const log = getChannel(msgnew, msgnew.guild.DB.eventChannels.mesEd?.channel);
if (!log || !msgnew.author) return;
const emb = defaultEventLogEmbed(msgnew.guild);
emb
const emb = defaultEventLogEmbed(msgnew.guild)
.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]`")

View file

@ -1,6 +1,6 @@
'use strict';
const { Structures, Guild, GuildMember, BanOptions } = require("discord.js"),
const { Structures, Guild, GuildMember, BanOptions, Role } = require("discord.js"),
{ database } = require("../database/mongo"),
{ errLog, defaultEventLogEmbed, defaultDateFormat, trySend } = require("./functions");
const { createSchedule } = require("../cmds/moderation/src/createSchedule");
@ -50,7 +50,7 @@ Structures.extend("Guild", u => {
* @param {string} userID - User ID
* @returns {object[]} Array of infractions objects
*/
async getInfractions(userID) {
getInfractions(userID) {
let ret = []
for (const [k, v] of this.DB.infractions)
if (v.by.map(r => r.id).includes(userID)) ret.push(v);
@ -194,7 +194,7 @@ Structures.extend("User", u => {
*/
async mute(guild, data, reason) {
if (!guild || !(guild instanceof Guild)) throw new TypeError("Guild is: " + guild);
if (!data?.infraction) throw new Error("Missing infraction id");
if (!data || !data.infraction) throw new Error("Missing infraction id");
const MEM = guild.member(this);
const CL = guild.member(this.client.user);
@ -269,17 +269,16 @@ Structures.extend("User", u => {
*/
async ban(guild, data, option) {
if (!guild || !(guild instanceof Guild)) throw new TypeError("Guild is: " + guild);
if (!data?.infraction) throw new Error("Missing infraction id");
if (!data || !data.infraction) throw new Error("Missing infraction id");
const MEM = guild.member(this);
const CL = guild.member(this.client.user);
if (!(CL.isAdmin || CL.hasPermission("BAN_MEMBERS")) ||
!(data.moderation.isAdmin || data.moderator.hasPermission("BAN_MEMBERS"))) throw new Error("Missing Permissions");
!(data.moderator.isAdmin || data.moderator.hasPermission("BAN_MEMBERS"))) throw new Error("Missing Permissions");
if (MEM) {
if (moderator.roles.highest.position < MEM.roles.highest.position ||
if (data.moderator.roles.highest.position < MEM.roles.highest.position ||
MEM.roles.highest.position > CL.roles.highest.position)
throw new Error("You can't mute someone with higher position than you <:nekokekLife:852865942530949160>");
throw new Error("You can't ban someone with higher position than you <:nekokekLife:852865942530949160>");
}
await guild.members.ban(this, option);
if (!guild.DB) await guild.dbLoad();
if (!this.bot) {
@ -289,8 +288,9 @@ Structures.extend("User", u => {
.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");
this.createDM().then(r => trySend(this.client, r, emb));
await this.createDM().then(r => trySend(this.client, r, emb));
}
await guild.members.ban(this, option);
const MC = guild.getTimedPunishment(this.id, "ban"),
TP = new TimedPunishment({ userID: this.id, duration: data.duration, infraction: data.infraction, type: "ban" });
@ -312,11 +312,9 @@ Structures.extend("User", u => {
emb.setTitle("You have been unbanned")
.setDescription("**Reason**\n" + reason);
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");
}
}
@ -374,7 +372,7 @@ Structures.extend("GuildMember", u => {
}
async dbLoad() {
return database.collection("GuildMember").findOne({ document: this.id }).then((r, e) => {
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 = {};
return this.DB = r;
@ -382,14 +380,14 @@ Structures.extend("GuildMember", u => {
}
async setDb(query, set) {
return database.collection("GuildMember").updateOne({ document: 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.id } },
{ upsert: true }).then((r, e) => {
if (e) return errLog(e, null, this.client);
return this.DB[query] = set;
});
}
async infractions() {
get infractions() {
return this.guild.getInfractions(this.id);
}
@ -442,6 +440,13 @@ Structures.extend("GuildMember", u => {
}
}
/**
* @param {string[]} roles
*/
async setLeaveRoles(roles = []) {
return this.setDb("leaveRoles", roles);
}
get isAdmin() { if (!this.client.owners.includes(this.user)) return this.hasPermission("ADMINISTRATOR"); else return true }
}
});