progress? maybe

This commit is contained in:
Neko-Life 2021-07-25 18:58:12 +07:00
parent 5a6de7b981
commit a4aceb0179
14 changed files with 208 additions and 62 deletions

20
Main.js
View file

@ -16,7 +16,7 @@ if (process.argv.includes("-d")) {
const sqlite = require('sqlite');
const configFile = require('./config.json');
const { errLog, trySend, noPerm, getUTCComparison, defaultEventLogEmbed, getChannel } = require('./resources/functions');
const { errLog, trySend, noPerm, getUTCComparison, defaultEventLogEmbed, getChannel, getUser } = require('./resources/functions');
const { join } = require('path');
const getColor = require("./resources/getColor");
const { timestampAt } = require("./resources/debug");
@ -199,4 +199,22 @@ process.on("uncaughtException", e => errLog(e, null, client));
process.on("unhandledRejection", e => errLog(e, null, client));
process.on("warning", e => errLog(e, null, client));
async function execPunishmentSchedule([guildID, userID, type]) {
if (!guildID || !userID || !type) throw new TypeError("Undefined param!");
let USER = client.users.resolve(userID);
if (!USER) USER = await client.users.fetch(userID);
if (!USER) throw new Error("Unknown user");
const GUILD = client.guilds.resolve(guildID);
if (!GUILD) throw new Error("Unknown guild");
if (!GUILD.DB) GUILD.dbLoad();
const CL = GUILD.member(client.user);
let ret;
if (type === "mute") {
ret = await USER.unmute(GUILD, CL, "Punishment expired");
} else {
ret = await USER.unban(GUILD, CL, "Punishment expired");
}
return ret;
}
client.login(configFile.token);

View file

@ -31,7 +31,7 @@ module.exports = class ban extends commando.Command {
async run(msg, arg) {
const args = parseDoubleDash(arg),
target = args?.shift();
let reason = "No reason provided", pDuration = {}, execTarget = [], resultMsg = "", daysToDeleteMessage = 0;
let reason = "No reason provided", pDuration = {}, execTarget = [], resultMsg = "", daysToDeleteMessages = 0;
if (!target || target.length < 1) return trySend(msg.client, msg, this.description); else {
const ET = await targetUser(msg, target);
@ -44,7 +44,7 @@ module.exports = class ban extends commando.Command {
if (ARG === "--" || ARG.trim().length < 1) continue;
if (ARG.startsWith("d ")) {
const U = ARG.slice(2).trim();
if (U.length > 0 && !/\D/.test(U)) daysToDeleteMessage = parseInt(U, 10); else return trySend(msg.client, msg, "Invalid number of days to delete messages!");
if (U.length > 0 && !/\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()))

View file

@ -126,15 +126,6 @@ module.exports = class mute extends commando.Command {
if (/Missing Permissions|someone with higher position/.test(e.message)) cant.push(EXEC.id);
else if (/already muted/.test(e.message)) already.push(EXEC.id); else console.log(e); continue;
}
if (!EXEC.bot) {
const emb = defaultEventLogEmbed(msg.guild);
emb.setTitle("You have been muted")
.setDescription("**Reason**\n" + reason)
.addField("At", defaultDateFormat(duration.invoked), true)
.addField("Until", duration.until ? defaultDateFormat(duration.until) : "Never", true)
.addField("For", duration.duration?.strings.join(" ") || "Indefinite", true);
EXEC.createDM().then(r => trySend(msg.client, r, emb));
}
}
infractionToDoc.executed = muted;
@ -143,23 +134,16 @@ module.exports = class mute extends commando.Command {
if (muted.length > 0) await msg.guild.addInfraction(infractionToDoc);
const NAME = msg.guild.id + "/" + infractionToDoc.infraction,
newUnmuteSchedule = {
name: NAME,
path: "./scheduler/unmute.js",
worker: {
argv: [NAME]
},
date: duration.until?.toJSDate()
};
let emb = defaultImageEmbed(msg, null, "Infraction #" + infractionToDoc.infraction);
const emb = defaultImageEmbed(msg, null, "Infraction #" + infractionToDoc.infraction);
let mutedStr = "", mutedArr = [];
if (muted.length > 0) for (const U of muted) {
const tU = "<@" + U + ">\n";
if ((mutedStr + tU).length < 1000) mutedStr += tU; else mutedArr.push(U);
}
if (mutedArr.length > 0) mutedStr += `and ${mutedArr.length} more...`;
emb.setDescription("**Reason**\n" + reason)
.addField("Muted", mutedStr || "`[NONE]`")
.addField("At", defaultDateFormat(duration.invoked), true)

View file

@ -0,0 +1,52 @@
'use strict';
const Bree = require("bree");
const { errLog } = require("../../../resources/functions");
const { join } = require("path"),
scheduler = require("../../../resources/scheduler"),
{ database } = require("../../../database/mongo"),
col = database.collection("Schedule");
/**
* @type {Bree}
*/
let jobManager;
async function createSchedule(client, { guildID, userID, type, until }) {
if (!client || !guildID || !userID || !type || !until) throw new TypeError("Undefined params!");
if (!jobManager) await init(client);
let path;
if (type === "mute") path = "./unmuteSc.js";
else if (type === "ban") path = "./unbanSc.js";
else throw new TypeError("Invalid type: " + type);
if (typeof until === "string") until = new Date(until);
const NAME = guildID + "/" + userID + "/" + type,
SC = {
name: NAME,
path: join(__dirname, path),
/**
* @type {import("worker_threads").WorkerOptions}
*/
worker: {
argv: [NAME]
},
date: until
};
try {
await col.updateOne({ document: NAME }, { $set: SC, $setOnInsert: { document: NAME } }, { upsert: true });
await jobManager.remove(NAME).catch(() => { })
jobManager.add(SC);
jobManager.start(NAME);
} catch (e) {
return errLog(e, null, client);
}
}
async function init(client) {
const jobs = await col.find({}).toArray();
jobManager = scheduler(client, jobs);
jobManager.start();
}

View file

@ -0,0 +1,4 @@
'use strict';
const NAME = process.argv[2]?.split(/\//);

View file

@ -43,23 +43,15 @@ module.exports = class unmute extends commando.Command {
await USER.unmute(msg.guild, msg.member, reason)
.then(() => {
success.push(USER.id);
if (!USER.bot) {
const emb = defaultEventLogEmbed(msg.guild);
emb.setTitle("You have been unmuted")
.setDescription("**Reason**\n" + reason);
USER.createDM().then(r => trySend(msg.client, r, emb));
}
})
.catch((e) => {
console.log(e);
if (/isn't muted in/.test(e.message)) return notMuted.push(USER.id);
cant.push(USER.id)
cant.push(USER.id);
});
}
let emb = defaultImageEmbed(msg, null, "Unmute");
const emb = defaultImageEmbed(msg, null, "Unmute");
emb.setDescription("**Reason**\n" + reason)
.addField("Unmuted", (success.length > 0 ? "<@" + success.join(">, <@") + ">" : "`[NONE]`"));
if (cant.length > 0) emb.addField("Can't unmute", "<@" + cant.join(">, <@") + ">");

View file

@ -4,6 +4,7 @@ const commando = require("@iceprod/discord.js-commando");
const { Message } = require("discord.js");
const { DateTime, Interval } = require("luxon");
const { trySend, getUser, defaultImageEmbed, splitOnLength, defaultDateFormat } = require("../../resources/functions");
const getColor = require("../../resources/getColor");
const { intervalToDuration } = require("../moderation/src/duration");
module.exports = class profile extends commando.Command {
@ -42,7 +43,8 @@ module.exports = class profile extends commando.Command {
RFS = splitOnLength(RI, 1010, ">, <@&"), INT = Interval.fromDateTimes(DateTime.fromJSDate(MEM.joinedAt), DateTime.now());
emb.addField("Joined", defaultDateFormat(MEM.joinedAt) + `\n(${intervalToDuration(INT).strings.join(" ")} ago)`)
.addField("Nick", `\`${MEM.displayName}\``);
.addField("Nick", `\`${MEM.displayName}\``)
.setColor(getColor(MEM.displayColor));
if (RFS[0]?.length > 0) {
for (const p of RFS) {

View file

@ -26,5 +26,6 @@
"chatChannel": "837178237322919966",
"guildLog": "840154722434154496",
"shardChannel": "851361670533218324",
"home": "772073587792281600"
"home": "772073587792281600",
"schedulerLog": "868682302111248394"
}

View file

@ -20,6 +20,7 @@
"zlib-sync": "^0.1.7"
},
"devDependencies": {
"@types/bree": "^6.2.1",
"@types/luxon": "^1.27.1"
}
}

View file

@ -1,10 +1,10 @@
'use strict';
const { GuildMember } = require("discord.js"),
{ DateTime } = require("luxon"),
{ DateTime, Interval } = require("luxon"),
{ getChannel, defaultEventLogEmbed, trySend, defaultDateFormat } = require("../functions"),
getColor = require("../getColor"),
{ DT_PRINT_FORMAT } = require("../../cmds/moderation/src/duration");
{ DT_PRINT_FORMAT, intervalToDuration } = require("../../cmds/moderation/src/duration");
/**
* Log newly joined Guild Member
@ -20,7 +20,8 @@ module.exports = (member) => {
.setTitle("`" + member.user.tag + "` joined")
.setThumbnail(member.user.displayAvatarURL({ format: "png", size: 4096, dynamic: true }))
.setColor(getColor("cyan"))
.addField("Registered", defaultDateFormat(member.user.createdAt))
.addField("Registered", defaultDateFormat(member.user.createdAt) +
`\n(${intervalToDuration(Interval.fromDateTimes(DateTime.fromJSDate(member.user.createdAt), DateTime.now())).strings.join(" ")} ago)`)
.setDescription(`<@!${member.id}> (${member.id}) just joined.\nWe have ${member.guild.memberCount} total members now.`);
return trySend(member.client, log, emb);
}

View file

@ -24,12 +24,11 @@ module.exports = (member) => {
.setTitle("`" + member.user.tag + "` left")
.setThumbnail(member.user.displayAvatarURL({ format: "png", size: 4096, dynamic: true }))
.setColor(getColor("yellow"))
.addField("Registered", defaultDateFormat(member.user.createdAt))
.addField("Joined", defaultDateFormat(member.joinedAt) + `\n(${intervalToDuration(INT).strings.join(" ")} ago)`)
.addField("Nick", "`" + member.displayName + "`")
.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 === 3 ? "Roles" : "", U.length > 0 ? "<@&" + U.join(">, <@&") + ">" : "`[NONE]`");
emb.addField(emb.fields.length === 2 ? "Roles" : "", U.length > 0 ? "<@&" + U.join(">, <@&") + ">" : "`[NONE]`");
}
return trySend(member.client, log, emb);
}

View file

@ -1,11 +1,22 @@
'use strict';
const bree = require("bree");
const Bree = require("bree");
const cabin = require("cabin");
const { Client } = require("discord.js");
const { errLog, trySend } = require("./functions"),
{ schedulerLog } = require("../config.json");
module.exports.scheduler = new bree({
// logger: new cabin(),
root: false,
workerMessageHandler: () => console.log,
errorHandler: () => console.error
});
/**
* @param {Client} client
* @param {object[]} jobs
* @returns {Bree}
*/
module.exports = (client, jobs = []) => {
return new Bree({
// logger: new cabin(),
root: false,
jobs: jobs,
workerMessageHandler: (a) => trySend(client, schedulerLog, a),
errorHandler: (e, m) => errLog(e, null, client, false, `\`${m?.threadId}\` \`${m?.name}\``)
});
}

View file

@ -1,5 +0,0 @@
'use strict';
require("@iceprod/discord.js-commando");
module.exports.unmuteExec = async function () {}

View file

@ -2,7 +2,7 @@
const { Structures, Guild, GuildMember, BanOptions } = require("discord.js"),
{ database } = require("../database/mongo"),
{ errLog } = require("./functions");
{ errLog, defaultEventLogEmbed, defaultDateFormat, trySend } = require("./functions");
const { TimedPunishment } = require("./classes");
Structures.extend("Guild", u => {
@ -193,30 +193,70 @@ Structures.extend("User", u => {
/**
* @param {Guild} guild
* @param {string} reason
* @param {{duration: object, saveTakenRoles: boolean, infraction: number, moderator: User}} data
* @param {{duration: object, saveTakenRoles: boolean, infraction: number, moderator: GuildMember}} data
*/
async mute(guild, data, reason) {
if (!guild || !(guild instanceof Guild)) throw new TypeError("Guild is " + typeof guild);
if (!guild || !(guild instanceof Guild)) throw new TypeError("Guild is: " + guild);
if (!data?.infraction) throw new Error("Missing infraction id");
if (!guild.DB) await guild.dbLoad();
const MEM = guild.member(this);
const CL = guild.member(this.client.user);
if (!CL.hasPermission("MANAGE_ROLES") ||
!data.moderator.hasPermission("MANAGE_ROLES")) throw new Error("Missing Permissions");
if (MEM) {
if (data.moderator.roles.highest.position < MEM.roles.highest.position || MEM.roles.highest.position > guild.member(this.client.user).roles.highest.position) throw new Error("You can't mute someone with higher position than you <:nekokekLife:852865942530949160>");
await MEM.mute(data, reason);
}
if (!guild.DB) await guild.dbLoad();
if (!this.bot) {
const emb = defaultEventLogEmbed(guild);
emb.setTitle("You have been muted")
.setDescription("**Reason**\n" + reason)
.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));
}
const MC = guild.getTimedPunishment(this.id, "mute"),
TP = new TimedPunishment({ userID: this.id, duration: data.duration, infraction: data.infraction, type: "mute" });
return { set: await guild.setTimedPunishment(TP), existing: MC }
}
/**
* @param {Guild} guild
* @param {GuildMember} moderator
* @param {string} reason
* @returns
*/
async unmute(guild, moderator, reason) {
if (!guild || !(guild instanceof Guild)) throw new TypeError("Guild is " + typeof guild);
if (!guild || !(guild instanceof Guild)) throw new TypeError("Guild is: " + guild);
const MEM = guild.member(this);
const CL = guild.member(this.client.user);
if (!CL.hasPermission("MANAGE_ROLES") ||
!moderator.hasPermission("MANAGE_ROLES")) throw new Error("Missing Permissions");
if (!guild.DB) await guild.dbLoad();
if (!this.bot) {
const emb = defaultEventLogEmbed(guild);
emb.setTitle("You have been unmuted")
.setDescription("**Reason**\n" + reason);
this.createDM().then(r => trySend(this.client, r, emb));
}
const MC = guild.getTimedPunishment(this.id, "mute");
if (!MC) throw new Error(this.tag + " isn't muted in " + guild.name);
const MEM = guild.member(this);
if (MEM) {
if (moderator.roles.highest.position < MEM.roles.highest.position || MEM.roles.highest.position > guild.member(this.client.user).roles.highest.position) throw new Error("You can't mute someone with higher position than you <:nekokekLife:852865942530949160>");
if (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>");
await MEM.unmute(reason);
}
return guild.removeTimedPunishment(this.id, "mute");
@ -224,10 +264,56 @@ Structures.extend("User", u => {
/**
* @param {Guild} guild
* @param {{duration: object, infraction: number, moderator: GuildMember}} data
* @param {BanOptions} option
*/
async ban(guild, option) {
guild.members.ban(this, option);
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");
const MEM = guild.member(this);
const CL = guild.member(this.client.user);
if (!CL.hasPermission("BAN_MEMBERS") ||
!data.moderator.hasPermission("BAN_MEMBERS")) throw new Error("Missing Permissions");
if (MEM) {
if (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>");
}
await guild.members.ban(this, option);
if (!guild.DB) await guild.dbLoad();
if (!this.bot) {
const emb = defaultEventLogEmbed(guild);
emb.setTitle("You have been banned")
.setDescription("**Reason**\n" + option.reason)
.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));
}
const MC = guild.getTimedPunishment(this.id, "ban"),
TP = new TimedPunishment({ userID: this.id, duration: data.duration, infraction: data.infraction, type: "ban" });
return { set: await guild.setTimedPunishment(TP), existing: MC }
}
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");
await guild.members.unban(this, reason);
if (!guild.DB) await guild.DB.dbLoad();
if (!this.bot) {
const emb = defaultEventLogEmbed(guild);
emb.setTitle("You have been unbanned")
.setDescription("**Reason**\n" + reason);
this.createDM().then(r => trySend(this.client, r, emb));
}
return guild.removeTimedPunishment(this.id, "ban");
}
}
});