1
0
mirror of https://github.com/toast-ts/Daggerbot-TS.git synced 2024-11-17 00:10:58 -05:00

Moderation improvements

This commit is contained in:
toast-ts 2024-02-04 13:09:33 +11:00
parent ffb9220064
commit 964b987a42
7 changed files with 24 additions and 10 deletions

View File

@ -8,7 +8,7 @@ export default class Case {
for (const channelID of logsArray) { for (const channelID of logsArray) {
const channel = await client.channels.fetch(channelID) as Discord.TextChannel; const channel = await client.channels.fetch(channelID) as Discord.TextChannel;
if (channel && channel.type === Discord.ChannelType.GuildText) { if (channel && channel.type === Discord.ChannelType.GuildText) {
const messages = await channel.messages.fetch({limit: 3}); const messages = await channel.messages.fetch({limit: 5});
messages.forEach(async message=>{ messages.forEach(async message=>{
if (message?.embeds[0]?.title && message?.embeds[0]?.title.match(new RegExp(`Case #${caseId}`))) { if (message?.embeds[0]?.title && message?.embeds[0]?.title.match(new RegExp(`Case #${caseId}`))) {
const findIndex = message?.embeds[0].fields.findIndex(x=>x.name === 'Reason'); const findIndex = message?.embeds[0].fields.findIndex(x=>x.name === 'Reason');
@ -36,8 +36,8 @@ export default class Case {
const cancelledBy = punishment.dataValues.expired ? await client.punishments.findByCancels(punishment.dataValues.case_id) : null; const cancelledBy = punishment.dataValues.expired ? await client.punishments.findByCancels(punishment.dataValues.case_id) : null;
const cancels = punishment.dataValues.cancels ? await client.punishments.findCase(punishment.dataValues.cancels) : null; const cancels = punishment.dataValues.cancels ? await client.punishments.findCase(punishment.dataValues.cancels) : null;
const embed = new client.embed().setColor(client.config.embedColor).setTimestamp(Number(punishment.dataValues.time)).setTitle(`${punishment.dataValues.type[0].toUpperCase()+punishment.dataValues.type.slice(1)} | Case #${punishment.dataValues.case_id}`).addFields( const embed = new client.embed().setColor(client.config.embedColor).setTimestamp(Number(punishment.dataValues.time)).setTitle(`${punishment.dataValues.type[0].toUpperCase()+punishment.dataValues.type.slice(1)} | Case #${punishment.dataValues.case_id}`).addFields(
{name: 'User', value: `${MessageTool.formatMention(punishment.dataValues.member, 'user')} \`${punishment.dataValues.member}\``, inline: true}, {name: 'User', value: `${punishment.member_name}\n${MessageTool.formatMention(punishment.dataValues.member, 'user')}\n\`${punishment.dataValues.member}\``, inline: true},
{name: 'Moderator', value: `${MessageTool.formatMention(punishment.dataValues.moderator, 'user')} \`${punishment.dataValues.moderator}\``, inline: true}, {name: 'Moderator', value: `${client.users.resolve(punishment.moderator).tag}\n${MessageTool.formatMention(punishment.dataValues.moderator, 'user')}\n\`${punishment.dataValues.moderator}\``, inline: true},
{name: '\u200b', value: '\u200b', inline: true}, {name: '\u200b', value: '\u200b', inline: true},
{name: 'Reason', value: `\`${punishment.reason || 'Reason unspecified'}\``, inline: true}) {name: 'Reason', value: `\`${punishment.reason || 'Reason unspecified'}\``, inline: true})
if (punishment.dataValues.duration) embed.addFields({name: 'Duration', value: `${Formatters.timeFormat(punishment.dataValues.duration, 100)}`}) if (punishment.dataValues.duration) embed.addFields({name: 'Duration', value: `${Formatters.timeFormat(punishment.dataValues.duration, 100)}`})

View File

@ -8,6 +8,7 @@ export default class Unpunish {
const punishment = await client.punishments.findCase(interaction.options.getInteger('case_id', true)); const punishment = await client.punishments.findCase(interaction.options.getInteger('case_id', true));
if (!punishment) return interaction.reply({content: 'Case ID is not found in database.', ephemeral: true}); if (!punishment) return interaction.reply({content: 'Case ID is not found in database.', ephemeral: true});
if (['unban', 'unmute', 'punishmentOverride'].includes(punishment.dataValues.type)) return interaction.reply({content: 'This case ID is immutable. (Informative case)', ephemeral: true}); if (['unban', 'unmute', 'punishmentOverride'].includes(punishment.dataValues.type)) return interaction.reply({content: 'This case ID is immutable. (Informative case)', ephemeral: true});
if (punishment.dataValues.expired) return interaction.reply({content: 'This case ID is already expired.', ephemeral: true});
const reason = interaction.options.getString('reason') ?? 'Reason unspecified'; const reason = interaction.options.getString('reason') ?? 'Reason unspecified';
await client.punishments.punishmentRemove(punishment.dataValues.case_id, interaction.user.id, reason, interaction); await client.punishments.punishmentRemove(punishment.dataValues.case_id, interaction.user.id, reason, interaction);

View File

@ -16,7 +16,7 @@ export default async(client:TClient, interaction: Discord.ChatInputCommandIntera
Logger.console('log', 'PunishmentLog', punishLog); Logger.console('log', 'PunishmentLog', punishLog);
(client.channels.cache.get(client.config.dcServer.channels.punishment_log) as Discord.TextChannel).send({embeds:[new client.embed().setColor(client.config.embedColor).setAuthor({name: interaction.user.username, iconURL: interaction.user.avatarURL({size:2048})}).setTitle('Punishment Log').setDescription(punishLog).setTimestamp()]}); (client.channels.cache.get(client.config.dcServer.channels.punishment_log) as Discord.TextChannel).send({embeds:[new client.embed().setColor(client.config.embedColor).setAuthor({name: interaction.user.username, iconURL: interaction.user.avatarURL({size:2048})}).setTitle('Punishment Log').setDescription(punishLog).setTimestamp()]});
if (!GuildMember.moderatable) return interaction.reply(`I cannot ${type} this user.`); if (GuildMember && !GuildMember?.moderatable) return interaction.reply(`I cannot ${type} this user.`);
if (interaction.user.id === User.id) return interaction.reply(`You cannot ${type} yourself.`); if (interaction.user.id === User.id) return interaction.reply(`You cannot ${type} yourself.`);
if (!GuildMember && !['unban', 'ban'].includes(type)) return interaction.reply(`You cannot ${type} someone who is not in the server.`); if (!GuildMember && !['unban', 'ban'].includes(type)) return interaction.reply(`You cannot ${type} someone who is not in the server.`);
if (User.bot) return interaction.reply(`You cannot ${type} a bot!`); if (User.bot) return interaction.reply(`You cannot ${type} a bot!`);

View File

@ -23,7 +23,7 @@ export default class GuildMemberAdd {
const usedInvite = newInvites.find((inv:Discord.Invite)=>client.invites.get(inv.code)?.uses < inv.uses); const usedInvite = newInvites.find((inv:Discord.Invite)=>client.invites.get(inv.code)?.uses < inv.uses);
newInvites.forEach((inv:Discord.Invite)=>client.invites.set(inv.code,{uses: inv.uses, creator: inv.inviterId, channel: inv.channel.name})); newInvites.forEach((inv:Discord.Invite)=>client.invites.set(inv.code,{uses: inv.uses, creator: inv.inviterId, channel: inv.channel.name}));
(client.channels.resolve(client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds: [ (client.channels.resolve(client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds: [
new client.embed().setColor(client.config.embedColorGreen).setTimestamp().setThumbnail(member.user.displayAvatarURL({size: 2048})).setTitle(`${isBot} Joined: ${member.user.username}`).setFooter({text: `Total members: ${index}${suffix}`}).addFields( new client.embed().setColor(client.config.embedColorGreen).setTimestamp().setThumbnail(member.user.displayAvatarURL({size: 2048})).setTitle(`${isBot} Joined: ${member.user.username}`).setFooter({text: `Total members: ${index}${suffix} | ID: ${member.user.id}`}).addFields(
{name: '🔹 Account Creation Date', value: `<t:${Math.round(member.user.createdTimestamp/1000)}>\n<t:${Math.round(member.user.createdTimestamp/1000)}:R>`}, {name: '🔹 Account Creation Date', value: `<t:${Math.round(member.user.createdTimestamp/1000)}>\n<t:${Math.round(member.user.createdTimestamp/1000)}:R>`},
{name: '🔹 Invite Data:', value: usedInvite ? `Invite: \`${usedInvite.code}\`\nCreated by: **${usedInvite.inviter?.username}**\nChannel: **#${usedInvite.channel.name}**` : 'No invite data could be fetched.'} {name: '🔹 Invite Data:', value: usedInvite ? `Invite: \`${usedInvite.code}\`\nCreated by: **${usedInvite.inviter?.username}**\nChannel: **#${usedInvite.channel.name}**` : 'No invite data could be fetched.'}
)]}); )]});

View File

@ -4,6 +4,7 @@ const client = new TClient;
client.init(); client.init();
import Logger from './helpers/Logger.js'; import Logger from './helpers/Logger.js';
import YTModule from './modules/YTModule.js'; import YTModule from './modules/YTModule.js';
import CacheServer from './components/CacheServer.js';
import MPModule, {refreshTimerSecs} from './modules/MPModule.js'; import MPModule, {refreshTimerSecs} from './modules/MPModule.js';
import UsernameHelper from './helpers/UsernameHelper.js'; import UsernameHelper from './helpers/UsernameHelper.js';
import {Punishment, RawGatewayPacket, RawMessageDelete, RawMessageUpdate} from 'src/interfaces'; import {Punishment, RawGatewayPacket, RawMessageDelete, RawMessageUpdate} from 'src/interfaces';
@ -52,6 +53,10 @@ setInterval(async()=>{
const punishments = await client.punishments.findInCache(); const punishments = await client.punishments.findInCache();
punishments.filter((x:Punishment)=>x.endTime && x.endTime <= now && !x.expired).forEach(async (punishment:Punishment)=>{ punishments.filter((x:Punishment)=>x.endTime && x.endTime <= now && !x.expired).forEach(async (punishment:Punishment)=>{
let key = `punishment_handled:${punishment.case_id}`;
if (await CacheServer.get(key, false)) return;
await CacheServer.set(key, true, false).then(async()=>await CacheServer.expiry(key, 35));
Logger.console('log', 'Punishment', `${punishment.member}\'s ${punishment.type} should expire now`); Logger.console('log', 'Punishment', `${punishment.member}\'s ${punishment.type} should expire now`);
Logger.console('log', 'Punishment', await client.punishments.punishmentRemove(punishment.case_id, client.user.id, 'Time\'s up!')); Logger.console('log', 'Punishment', await client.punishments.punishmentRemove(punishment.case_id, client.user.id, 'Time\'s up!'));
}); });

1
src/interfaces.d.ts vendored
View File

@ -3,6 +3,7 @@ import {ColorResolvable, PresenceData, APIUser} from 'discord.js';
export interface Punishment { export interface Punishment {
case_id: number; case_id: number;
type: string; type: string;
member_name: string;
member: string; member: string;
moderator: string; moderator: string;
expired?: boolean; expired?: boolean;

View File

@ -11,6 +11,7 @@ import Formatters from '../helpers/Formatters.js';
class punishments extends Model { class punishments extends Model {
declare public case_id: number; declare public case_id: number;
declare public type: string; declare public type: string;
declare public member_name: string;
declare public member: string; declare public member: string;
declare public moderator: string; declare public moderator: string;
declare public expired: boolean; declare public expired: boolean;
@ -38,6 +39,10 @@ export class PunishmentsSvc {
type: DataTypes.STRING, type: DataTypes.STRING,
allowNull: false allowNull: false
}, },
member_name: {
type: DataTypes.STRING,
allowNull: true
},
member: { member: {
type: DataTypes.STRING, type: DataTypes.STRING,
allowNull: false allowNull: false
@ -124,7 +129,7 @@ export class PunishmentsSvc {
.setColor(this.client.config.embedColor) .setColor(this.client.config.embedColor)
.setTitle(`${punishment.type[0].toUpperCase() + punishment.type.slice(1)} | Case #${punishment.case_id}`) .setTitle(`${punishment.type[0].toUpperCase() + punishment.type.slice(1)} | Case #${punishment.case_id}`)
.addFields( .addFields(
{name: '🔹 User', value: `<@${punishment.member}>\n\`${punishment.member}\``, inline: true}, {name: '🔹 User', value: `${punishment.member_name}\n<@${punishment.member}>\n\`${punishment.member}\``, inline: true},
{name: '🔹 Moderator', value: `<@${punishment.moderator}>\n\`${punishment.moderator}\``, inline: true}, {name: '🔹 Moderator', value: `<@${punishment.moderator}>\n\`${punishment.moderator}\``, inline: true},
{name: '\u200b', value: '\u200b', inline: true}, {name: '\u200b', value: '\u200b', inline: true},
{name: '🔹 Reason', value: `\`${punishment.reason}\``, inline: true} {name: '🔹 Reason', value: `\`${punishment.reason}\``, inline: true}
@ -150,7 +155,7 @@ export class PunishmentsSvc {
const {time, interaction} = options; const {time, interaction} = options;
const now = Date.now(); const now = Date.now();
const guild = this.client.guilds.cache.get(this.client.config.dcServer.id) as Discord.Guild; const guild = this.client.guilds.cache.get(this.client.config.dcServer.id) as Discord.Guild;
const punishment:Punishment = {type, case_id: await this.generateCaseId(), member: user.id, reason, moderator, time: now}; const punishment:Punishment = {type, case_id: await this.generateCaseId(), member_name: user.username, member: user.id, reason, moderator, time: now};
const inOrFromBoolean = ['warn', 'mute', 'remind'].includes(type) ? 'in' : 'from'; const inOrFromBoolean = ['warn', 'mute', 'remind'].includes(type) ? 'in' : 'from';
const auditLogReason = `${reason ?? 'Reason unspecified'} | Case #${punishment.case_id}`; const auditLogReason = `${reason ?? 'Reason unspecified'} | Case #${punishment.case_id}`;
const embed = new this.client.embed() const embed = new this.client.embed()
@ -172,7 +177,7 @@ export class PunishmentsSvc {
if (['ban', 'softban'].includes(type)) { if (['ban', 'softban'].includes(type)) {
const alreadyBanned = await guild.bans.fetch(user.id).catch(()=>null); // 172800 seconds is 48 hours, just for future reference const alreadyBanned = await guild.bans.fetch(user.id).catch(()=>null); // 172800 seconds is 48 hours, just for future reference
if (!alreadyBanned) punishmentResult = await guild.bans.create(user.id, {reason: auditLogReason, deleteMessageSeconds: 172800}).catch((err:Error)=>err.message); if (!alreadyBanned) punishmentResult = await guild.bans.create(user.id, {reason: auditLogReason, deleteMessageSeconds: 172800}).catch((err:Error)=>err.message);
else punishmentResult = 'This user already exists in the guild\'s ban list.'; else punishmentResult = `This user already exists in the guild\'s ban list.\nReason: \`${alreadyBanned?.reason}\``;
} else if (type === 'kick') punishmentResult = await guildUser?.kick(auditLogReason).catch((err:Error)=>err.message); } else if (type === 'kick') punishmentResult = await guildUser?.kick(auditLogReason).catch((err:Error)=>err.message);
else if (type === 'mute') punishmentResult = await guildUser?.timeout(millisecondTime, auditLogReason).catch((err:Error)=>err.message); else if (type === 'mute') punishmentResult = await guildUser?.timeout(millisecondTime, auditLogReason).catch((err:Error)=>err.message);
@ -192,6 +197,7 @@ export class PunishmentsSvc {
else await this.model.create({ else await this.model.create({
case_id: punishment.case_id, case_id: punishment.case_id,
type: punishment.type, type: punishment.type,
member_name: punishment.member_name,
member: punishment.member, member: punishment.member,
moderator: punishment.moderator, moderator: punishment.moderator,
expired: punishment.expired, expired: punishment.expired,
@ -217,7 +223,7 @@ export class PunishmentsSvc {
const user = await this.client.users.fetch(punishment.member); const user = await this.client.users.fetch(punishment.member);
const guildUser:Discord.GuildMember = await guild.members.fetch(punishment.member).catch(()=>null); const guildUser:Discord.GuildMember = await guild.members.fetch(punishment.member).catch(()=>null);
let removePunishmentData:Punishment = {type: `un${punishment.type}`, case_id: ID, cancels: punishment.case_id, member: punishment.member, reason, moderator, time: now}; let removePunishmentData:Punishment = {type: `un${punishment.type}`, case_id: ID, cancels: punishment.case_id, member_name: punishment.member_name, member: punishment.member, reason, moderator, time: now};
let removePunishmentResult:any; let removePunishmentResult:any;
if (punishment.type === 'ban') removePunishmentResult = await guild.bans.remove(punishment.member, auditLogReason).catch((err:Error)=>err.message); if (punishment.type === 'ban') removePunishmentResult = await guild.bans.remove(punishment.member, auditLogReason).catch((err:Error)=>err.message);
@ -236,6 +242,7 @@ export class PunishmentsSvc {
this.model.create({ this.model.create({
case_id: removePunishmentData.case_id, case_id: removePunishmentData.case_id,
type: removePunishmentData.type, type: removePunishmentData.type,
member_name: removePunishmentData.member_name,
member: removePunishmentData.member, member: removePunishmentData.member,
moderator: removePunishmentData.moderator, moderator: removePunishmentData.moderator,
expired: removePunishmentData.expired, expired: removePunishmentData.expired,
@ -252,7 +259,7 @@ export class PunishmentsSvc {
.setColor(this.client.config.embedColor) .setColor(this.client.config.embedColor)
.setTitle(`${removePunishmentData.type[0].toUpperCase() + removePunishmentData.type.slice(1)} | Case #${removePunishmentData.case_id}`) .setTitle(`${removePunishmentData.type[0].toUpperCase() + removePunishmentData.type.slice(1)} | Case #${removePunishmentData.case_id}`)
.setDescription(`${user.username}\n<@${user.id}>\n\`${user.id}\``) .setDescription(`${user.username}\n<@${user.id}>\n\`${user.id}\``)
.addFields({name: 'Reason', value: `\`${reason}\``}, {name: 'Overwrites', value: `Case #${punishment.case_id}`}) .addFields({name: 'Reason', value: `\`${reason}\``, inline: true}, {name: 'Overwrites', value: `Case #${punishment.case_id}`, inline: true})
]}); ]});
else return `Successfully un${this.getPastTense(removePunishmentData.type.replace('un', ''))} ${user.username} (\`${user.id}\`) for ${reason}` else return `Successfully un${this.getPastTense(removePunishmentData.type.replace('un', ''))} ${user.username} (\`${user.id}\`) for ${reason}`
} }