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

Compare commits

..

No commits in common. "137a0ae7b84f64471b6ac9ad2f343a35b9593dab" and "d0d65c298687bb178623b3a20770eb15a5e3fac4" have entirely different histories.

14 changed files with 88 additions and 34 deletions

View File

@ -19,7 +19,7 @@ export default class Case {
} }
} }
static run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){ static run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
if (!MessageTool.isModerator(interaction.member)) return MessageTool.youNeedRole(interaction, 'dcmod'); if (!MessageTool.isStaff(interaction.member)) return MessageTool.youNeedRole(interaction, 'dcmod');
const caseId = interaction.options.getInteger('id'); const caseId = interaction.options.getInteger('id');
({ ({
update: async()=>{ update: async()=>{
@ -49,14 +49,14 @@ export default class Case {
const user = (interaction.options.getUser('user') as Discord.User); const user = (interaction.options.getUser('user') as Discord.User);
if (user.bot) return interaction.reply(`**${user.username}**'s punishment history cannot be viewed as they are a bot.`) if (user.bot) return interaction.reply(`**${user.username}**'s punishment history cannot be viewed as they are a bot.`)
const punishments = await client.punishments.getAllCases(); const punishments = await client.punishments.getAllCases();
const userPunishmentData = punishments.filter(x=>x.dataValues.member === user.id).sort((a,b)=>b.dataValues.time-a.dataValues.time); const userPunishmentData = punishments.filter(x=>x.dataValues.member === user.id);
const userPunishment = userPunishmentData.map(punishment=>{ const userPunishment = userPunishmentData.sort((a,b)=>a.dataValues.time-b.dataValues.time).map(punishment=>{
return { return {
name: `${punishment.dataValues.type[0].toUpperCase()+punishment.dataValues.type.slice(1)} | Case #${punishment.dataValues.case_id}`, name: `${punishment.dataValues.type[0].toUpperCase()+punishment.dataValues.type.slice(1)} | Case #${punishment.dataValues.case_id}`,
value: `Reason: \`${punishment.dataValues.reason}\`\n${punishment.dataValues.duration ? `Duration: ${Formatters.timeFormat(punishment.dataValues.duration, 3)}\n` : ''}Moderator: ${MessageTool.formatMention(punishment.dataValues.moderator, 'user')}${punishment.dataValues.expired ? `\nOverwritten by Case #${punishments.find(x=>x.dataValues.cancels===punishment.dataValues.case_id)?.case_id}` : ''}${punishment.dataValues.cancels ? `\nOverwrites Case #${punishment.dataValues.cancels}` : ''}` value: `Reason: \`${punishment.dataValues.reason}\`\n${punishment.dataValues.duration ? `Duration: ${Formatters.timeFormat(punishment.dataValues.duration, 3)}\n` : ''}Moderator: ${MessageTool.formatMention(punishment.dataValues.moderator, 'user')}${punishment.dataValues.expired ? `\nOverwritten by Case #${punishments.find(x=>x.dataValues.cancels===punishment.dataValues.case_id)?.case_id}` : ''}${punishment.dataValues.cancels ? `\nOverwrites Case #${punishment.dataValues.cancels}` : ''}`
} }
}); });
if (!userPunishment.length) return interaction.reply(`**${user.username}** has a clean record.`) if (!punishments || !userPunishment) return interaction.reply(`**${user.username}** has a clean record.`)
const pageNum = interaction.options.getInteger('page') ?? 1; const pageNum = interaction.options.getInteger('page') ?? 1;
return interaction.reply({embeds: [new client.embed().setColor(client.config.embedColor).setTitle(`${user.username}'s punishment history`).setDescription(`**ID:** \`${user.id}\``).setFooter({text: `${userPunishment.length} total punishments. Viewing page ${pageNum} out of ${Math.ceil(userPunishment.length/6)}.`}).addFields(userPunishment.slice((pageNum - 1) * 6, pageNum * 6))]}); return interaction.reply({embeds: [new client.embed().setColor(client.config.embedColor).setTitle(`${user.username}'s punishment history`).setDescription(`**ID:** \`${user.id}\``).setFooter({text: `${userPunishment.length} total punishments. Viewing page ${pageNum} out of ${Math.ceil(userPunishment.length/6)}.`}).addFields(userPunishment.slice((pageNum - 1) * 6, pageNum * 6))]});
} }

View File

@ -76,7 +76,7 @@ export default class Developer {
else if (stdout.includes('Already up to date')) hammondYouIdiot.edit('Repository is currently up to date.'); else if (stdout.includes('Already up to date')) hammondYouIdiot.edit('Repository is currently up to date.');
else hammondYouIdiot.edit('Running `yarn tsc`...').then(()=>exec('yarn tsc', {windowsHide:true}, (err:Error)=>{ else hammondYouIdiot.edit('Running `yarn tsc`...').then(()=>exec('yarn tsc', {windowsHide:true}, (err:Error)=>{
if (err) hammondYouIdiot.edit(`\`\`\`${UsernameHelper(err.message)}\`\`\``); if (err) hammondYouIdiot.edit(`\`\`\`${UsernameHelper(err.message)}\`\`\``);
else if (interaction.options.getBoolean('restart')) hammondYouIdiot.edit(msgBody + `\nUptime: **${Formatters.timeFormat(process.uptime()*1000, 4, {longNames:true, commas:true})}**`).then(()=>process.exit(0)); else if (interaction.options.getBoolean('restart')) hammondYouIdiot.edit(msgBody + `\nUptime: ${Formatters.timeFormat(process.uptime()*1000, 4, {longNames:true, commas:true})}`).then(()=>process.exit(0));
else hammondYouIdiot.edit(msgBody); else hammondYouIdiot.edit(msgBody);
})); }));
}); });

View File

@ -4,7 +4,7 @@ import HookMgr from '../components/HookManager.js';
import MessageTool from '../helpers/MessageTool.js'; import MessageTool from '../helpers/MessageTool.js';
export default class ProhibitedWords { export default class ProhibitedWords {
static async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){ static async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
if (!MessageTool.isModerator(interaction.member) && !client.config.whitelist.includes(interaction.member.id)) return MessageTool.youNeedRole(interaction, 'admin'); if (!MessageTool.isStaff(interaction.member) && !client.config.whitelist.includes(interaction.member.id)) return MessageTool.youNeedRole(interaction, 'admin');
const word = interaction.options.getString('word'); const word = interaction.options.getString('word');
const wordExists = await client.prohibitedWords.findWord(word); const wordExists = await client.prohibitedWords.findWord(word);
({ ({

View File

@ -3,7 +3,7 @@ import TClient from '../client.js';
import MessageTool from '../helpers/MessageTool.js'; import MessageTool from '../helpers/MessageTool.js';
export default class Purge { export default class Purge {
static async run(_client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){ static async run(_client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
if (!MessageTool.isModerator(interaction.member)) return MessageTool.youNeedRole(interaction, 'dcmod'); if (!MessageTool.isStaff(interaction.member)) return MessageTool.youNeedRole(interaction, 'dcmod');
const amount = interaction.options.getInteger('amount') as number; const amount = interaction.options.getInteger('amount') as number;
if (amount > 100) return interaction.reply({content: 'Discord API limits purging up to 100 messages.', ephemeral: true}) if (amount > 100) return interaction.reply({content: 'Discord API limits purging up to 100 messages.', ephemeral: true})
const user = interaction.options.getUser('user'); const user = interaction.options.getUser('user');

View File

@ -4,7 +4,7 @@ import Logger from '../helpers/Logger.js';
import MessageTool from '../helpers/MessageTool.js'; import MessageTool from '../helpers/MessageTool.js';
export default class Unpunish { export default class Unpunish {
static async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){ static async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
if (!MessageTool.isModerator(interaction.member as Discord.GuildMember)) return MessageTool.youNeedRole(interaction, 'dcmod'); if (!MessageTool.isStaff(interaction.member as Discord.GuildMember)) return MessageTool.youNeedRole(interaction, 'dcmod');
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});

View File

@ -3,7 +3,9 @@ import TClient from '../client.js';
import Logger from '../helpers/Logger.js'; import Logger from '../helpers/Logger.js';
export default class Automoderator { export default class Automoderator {
private static lockQuery:Set<Discord.Snowflake> = new Set(); private static lockQuery:Set<Discord.Snowflake> = new Set();
static scanMsg =(message:Discord.Message)=>message.content.toLowerCase().replaceAll(/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?\n?0-9]|[]|ing\b/g, '').split(' ').join(''); static scanMsg(message:Discord.Message) {
return message.content.toLowerCase().replaceAll(/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?\n?0-9]|[]|ing\b/g, '').split(' ').join('');
}
static async repeatedMessages(client:TClient, message:Discord.Message, thresholdTime:number, thresholdAmount:number, type:string, duration:string, reason:string) { static async repeatedMessages(client:TClient, message:Discord.Message, thresholdTime:number, thresholdAmount:number, type:string, duration:string, reason:string) {
const now = Date.now(); const now = Date.now();

View File

@ -29,8 +29,12 @@ export default class CacheServer {
if (jsonMode) return await RedisClient.json.set(key, '.', value); if (jsonMode) return await RedisClient.json.set(key, '.', value);
else return await RedisClient.set(key, JSON.stringify(value)); else return await RedisClient.set(key, JSON.stringify(value));
} }
public static expiry = async(key:any, time:number)=>await RedisClient.expire(key, time); // NOTE: time is in seconds, not milliseconds -- you know what you did wrong public static async expiry(key:any, time:number) {
public static delete = async(key:any)=>await RedisClient.del(key); return await RedisClient.expire(key, time); // NOTE: time is in seconds, not milliseconds -- you know what you did wrong
}
public static async delete(key:any) {
return await RedisClient.del(key);
}
public static init() { public static init() {
try { try {
RedisClient.connect(); RedisClient.connect();

View File

@ -14,7 +14,9 @@ export default class HookMgr {
this.webhookId = webhookId; this.webhookId = webhookId;
} }
protected channelFetch = async(client:TClient, channel:ChannelList)=>await client.channels.fetch(config.dcServer.channels[channel]) as Discord.TextChannel; protected async channelFetch(client:TClient, channel:ChannelList) {
return await client.channels.fetch(config.dcServer.channels[channel]) as Discord.TextChannel;
}
protected async fetch(client:TClient, channel:ChannelList, webhookId:Discord.Snowflake) { protected async fetch(client:TClient, channel:ChannelList, webhookId:Discord.Snowflake) {
const hookInstance = await (await this.channelFetch(client, channel)).fetchWebhooks().then(x=>x.find(y=>y.id===webhookId)); const hookInstance = await (await this.channelFetch(client, channel)).fetchWebhooks().then(x=>x.find(y=>y.id===webhookId));
if (!hookInstance) throw new Error('[HookManager] Webhook not found.'); if (!hookInstance) throw new Error('[HookManager] Webhook not found.');

View File

@ -30,13 +30,21 @@ export class DailyMsgsSvc {
}) })
this.model.sync(); this.model.sync();
} }
nukeDays = async()=>await this.model.destroy({truncate: true}); async nukeDays() {
fetchDays = async()=>await this.model.findAll(); return await this.model.destroy({truncate: true})
// Drop a nuclear bomb on the table.
}
async fetchDays() {
return await this.model.findAll();
// Fetch every rows from database.
}
async newDay(formattedDate:number, total:number) { async newDay(formattedDate:number, total:number) {
if (await this.model.findOne({where: {day: formattedDate}})) return console.log('This day already exists!') if (await this.model.findOne({where: {day: formattedDate}})) return console.log('This day already exists!')
return await this.model.create({day: formattedDate, total: total}); return await this.model.create({day: formattedDate, total: total});
// Save previous day's total messages into database when a new day starts. // Save previous day's total messages into database when a new day starts.
} }
updateDay = async(formattedDate:number, total:number)=>await this.model.update({total: total}, {where: {day: formattedDate}}); async updateDay(formattedDate:number, total:number) {
return await this.model.update({total: total}, {where: {day: formattedDate}});
// THIS IS FOR DEVELOPMENT PURPOSES ONLY, NOT TO BE USED IN LIVE ENVIRONMENT! // THIS IS FOR DEVELOPMENT PURPOSES ONLY, NOT TO BE USED IN LIVE ENVIRONMENT!
} }
}

View File

@ -26,7 +26,9 @@ export class ProhibitedWordsSvc {
}) })
this.model.sync(); this.model.sync();
} }
findWord = async(word:string)=>await this.model.findByPk(word); async findWord(word:string) {
return await this.model.findByPk(word);
}
async importWords(file:string) { async importWords(file:string) {
const jsonData = await new Promise<string>((resolve, reject)=>{ const jsonData = await new Promise<string>((resolve, reject)=>{
get(file, res=>{ get(file, res=>{
@ -46,7 +48,13 @@ export class ProhibitedWordsSvc {
throw new Error(`Failed to insert words into Postgres database: ${err.message}`) throw new Error(`Failed to insert words into Postgres database: ${err.message}`)
} }
} }
getAllWords = async()=>await this.model.findAll(); async getAllWords() {
insertWord = async(word:string)=>await this.model.create({word: word}); return await this.model.findAll();
removeWord = async(word:string)=>await this.model.destroy({where: {word: word}}) }
async insertWord(word:string) {
return await this.model.create({word: word})
}
async removeWord(word:string) {
return await this.model.destroy({where: {word: word}})
}
} }

View File

@ -82,9 +82,15 @@ export class PunishmentsSvc {
const findCase = this.findCase(caseId); const findCase = this.findCase(caseId);
if (findCase) return this.model.update({reason: reason}, {where: {case_id: caseId}}); if (findCase) return this.model.update({reason: reason}, {where: {case_id: caseId}});
} }
findCase =(caseId:number)=>this.model.findOne({where: {case_id: caseId}}); async findCase(caseId:number) {
findByCancels =(caseId:number)=>this.model.findOne({where: {cancels: caseId}}) return this.model.findOne({where: {case_id: caseId}});
getAllCases =()=>this.model.findAll(); }
async findByCancels(caseId:number) {
return this.model.findOne({where: {cancels: caseId}})
}
async getAllCases() {
return this.model.findAll();
}
async generateCaseId() { async generateCaseId() {
const result = await this.model.findAll(); const result = await this.model.findAll();
return Math.max(...result.map((x:Punishment)=>x.case_id), 0) + 1; return Math.max(...result.map((x:Punishment)=>x.case_id), 0) + 1;
@ -101,7 +107,7 @@ export class PunishmentsSvc {
async findInCache():Promise<any> { async findInCache():Promise<any> {
const cacheKey = 'punishments'; const cacheKey = 'punishments';
const cachedResult = await CacheServer.get(cacheKey, true); const cachedResult = await CacheServer.get(cacheKey, true);
let result:any; let result;
if (cachedResult) result = cachedResult; if (cachedResult) result = cachedResult;
else { else {
result = await this.model.findAll(); result = await this.model.findAll();
@ -158,7 +164,13 @@ export class PunishmentsSvc {
const durText = millisecondTime ? ` for ${Formatters.timeFormat(millisecondTime, 4, {longNames: true, commas: true})}` : ''; const durText = millisecondTime ? ` for ${Formatters.timeFormat(millisecondTime, 4, {longNames: true, commas: true})}` : '';
if (time) embed.addFields({name: 'Duration', value: durText}); if (time) embed.addFields({name: 'Duration', value: durText});
if (guildUser) await guildUser.send(`You've been ${this.getPastTense(type)} ${inOrFromBoolean} **${guild.name}**${durText}\n\`${reason}\` (Case #${punishment.case_id})`).catch(()=>embed.setFooter({text: 'Unable to DM a member'})); if (guildUser) {
try {
await guildUser.send(`You've been ${this.getPastTense(type)} ${inOrFromBoolean} **${guild.name}**${durText}\n\`${reason}\` (Case #${punishment.case_id})`)
} catch {
embed.setFooter({text: 'Unable to DM a member'})
}
}
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

View File

@ -40,8 +40,16 @@ export class SuggestionsSvc {
}) })
this.model.sync(); this.model.sync();
} }
fetchById = async(id:number)=>await this.model.findByPk(id); async fetchById(id:number) {
updateStatus = async(id:number, status:string)=>await this.model.update({status: status}, {where: {id: id}}); return await this.model.findByPk(id);
create =(userid:string, description:string)=>this.model.create({userid: userid, suggestion: description, status: 'Pending'}) }
delete =(id:number)=>this.model.destroy({where: {id: id}}); async updateStatus(id:number, status:string) {
return await this.model.update({status: status}, {where: {id: id}})
}
async create(userid:string, description:string) {
return this.model.create({userid: userid, suggestion: description, status: 'Pending'})
}
async delete(id:number) {
return this.model.destroy({where: {id: id}});
}
} }

View File

@ -47,9 +47,15 @@ export class UserLevelsSvc {
}); });
this.model.sync(); this.model.sync();
} }
fetchEveryone = async()=>await this.model.findAll(); async fetchEveryone() {
fetchUser = async(userId:string)=>await this.model.findByPk(userId); return await this.model.findAll();
deleteUser = async(userId:string)=>await this.model.destroy({where: {id: userId}}); }
async fetchUser(userId:string) {
return await this.model.findByPk(userId);
}
async deleteUser(userId:string) {
return await this.model.destroy({where: {id: userId}});
}
async modifyUser(userId:string, updatedMessages:number) { async modifyUser(userId:string, updatedMessages:number) {
await this.model.update({messages: updatedMessages}, {where: {id: userId}}); await this.model.update({messages: updatedMessages}, {where: {id: userId}});
return (await this.model.findByPk(userId)).dataValues; return (await this.model.findByPk(userId)).dataValues;

View File

@ -34,11 +34,15 @@ export class YouTubeChannelsSvc {
}) })
this.model.sync(); this.model.sync();
} }
async getChannels() {
return await this.model.findAll();
}
async addChannel(YTChannelID:string, DCChannelID:string, DCRole:string) { async addChannel(YTChannelID:string, DCChannelID:string, DCRole:string) {
if (await this.model.findOne({where: {ytchannel: YTChannelID}})) return false; if (await this.model.findOne({where: {ytchannel: YTChannelID}})) return false;
await this.model.create({ytchannel: YTChannelID, dcchannel: DCChannelID, dcrole: DCRole}); await this.model.create({ytchannel: YTChannelID, dcchannel: DCChannelID, dcrole: DCRole});
return true; return true;
} }
delChannel = async(YTChannelID:string)=>await this.model.destroy({where: {ytchannel: YTChannelID}}); async delChannel(YTChannelID:string) {
getChannels = async()=>await this.model.findAll(); return await this.model.destroy({where: {ytchannel: YTChannelID}});
}
} }