mirror of
https://github.com/danbulant/Shasha
synced 2026-06-17 21:31:08 +00:00
progress? maybe
This commit is contained in:
parent
5a6de7b981
commit
a4aceb0179
14 changed files with 208 additions and 62 deletions
20
Main.js
20
Main.js
|
|
@ -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);
|
||||
|
|
@ -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()))
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
52
cmds/moderation/src/createSchedule.js
Normal file
52
cmds/moderation/src/createSchedule.js
Normal 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();
|
||||
}
|
||||
4
cmds/moderation/src/unmuteSc.js
Normal file
4
cmds/moderation/src/unmuteSc.js
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
'use strict';
|
||||
|
||||
const NAME = process.argv[2]?.split(/\//);
|
||||
|
||||
|
|
@ -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(">, <@") + ">");
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -26,5 +26,6 @@
|
|||
"chatChannel": "837178237322919966",
|
||||
"guildLog": "840154722434154496",
|
||||
"shardChannel": "851361670533218324",
|
||||
"home": "772073587792281600"
|
||||
"home": "772073587792281600",
|
||||
"schedulerLog": "868682302111248394"
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@
|
|||
"zlib-sync": "^0.1.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bree": "^6.2.1",
|
||||
"@types/luxon": "^1.27.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}\``)
|
||||
});
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
require("@iceprod/discord.js-commando");
|
||||
|
||||
module.exports.unmuteExec = async function () {}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue