From a90bf9f4588412aa25048760d48d09ddf3151b68 Mon Sep 17 00:00:00 2001 From: toast-ts <96593068+toast-ts@users.noreply.github.com> Date: Mon, 25 Dec 2023 14:02:59 +1100 Subject: [PATCH] Fix a few things that flew under the radar --- .dockerignore | 10 ---------- src/client.ts | 4 ++-- src/commands/dev.ts | 2 +- src/commands/mp.ts | 8 ++++---- src/commands/purge.ts | 2 +- src/commands/statistics.ts | 2 +- src/commands/whois.ts | 4 ++-- src/components/CanvasGraph.ts | 2 +- src/events/guildBanAdd.ts | 4 ++-- src/events/guildBanRemove.ts | 4 ++-- src/events/messageDelete.ts | 5 ++--- src/events/messageReactionAdd.ts | 2 +- src/events/messageReactionRemove.ts | 2 +- src/events/messageUpdate.ts | 3 +-- src/helpers/ConfigHelper.ts | 2 +- src/helpers/PalletLibrary.ts | 2 +- src/index.ts | 4 ++-- src/models/punishments.ts | 6 +++--- src/modules/MPModule.ts | 2 +- 19 files changed, 29 insertions(+), 41 deletions(-) delete mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index c80ec64..0000000 --- a/.dockerignore +++ /dev/null @@ -1,10 +0,0 @@ -botStartup.bat -.ncurc.json -.gitignore -README.md -.github -.vscode -.yarn/sdks -dist/ -docker-compose.yml -startWithYarn.cjs diff --git a/src/client.ts b/src/client.ts index f652965..1bb5917 100644 --- a/src/client.ts +++ b/src/client.ts @@ -9,7 +9,7 @@ interface IRepeatedMessages { import Discord from 'discord.js'; import ConfigHelper from './helpers/ConfigHelper.js'; import {readdirSync} from 'node:fs'; -import {Config} from './interfaces'; +import {Config} from 'src/interfaces'; import { DailyMsgsSvc, UserLevelsSvc, BonkCountSvc, MPServerSvc, PunishmentsSvc, ProhibitedWordsSvc, @@ -24,7 +24,7 @@ import TSClient from './helpers/TSClient.js'; export default class TClient extends Discord.Client { public invites: Map = new Map(); public commands: Discord.Collection = new Discord.Collection(); - public registry: Array = []; + public registry: Discord.ApplicationCommandDataResolvable[] = []; public config: Config; public embed: typeof Discord.EmbedBuilder = Discord.EmbedBuilder; public collection: typeof Discord.Collection = Discord.Collection; diff --git a/src/commands/dev.ts b/src/commands/dev.ts index d0d1a71..eedf0e9 100644 --- a/src/commands/dev.ts +++ b/src/commands/dev.ts @@ -71,7 +71,7 @@ export default class Developer { deletion: repoData.stats.deletions.toLocaleString('en-US') }; const msgBody = MessageTool.concatMessage( - `[Commit pulled:](<${repoData.commit.url}>)`, + `[Commit pulled](<${repoData.commit.url}>)`, `Message: **${repoData.commit.message.length === 0 ? '*No commit message*' : repoData.commit.message}**`, `Author: **${repoData.commit.author.name}**`, 'Changes', diff --git a/src/commands/mp.ts b/src/commands/mp.ts index 9cab7a2..216fa0a 100644 --- a/src/commands/mp.ts +++ b/src/commands/mp.ts @@ -5,7 +5,7 @@ import CanvasBuilder from '../components/CanvasGraph.js'; import RanIntoHumor from '../helpers/RanIntoHumor.js'; import MessageTool from '../helpers/MessageTool.js'; import PalletLibrary from '../helpers/PalletLibrary.js'; -import {FSData} from '../interfaces'; +import {FSData} from 'src/interfaces'; import {requestServerData, mpModuleDisabled, refreshTimerSecs, playtimeStat} from '../modules/MPModule.js'; async function fetchData(client:TClient, interaction:Discord.ChatInputCommandInteraction, serverName:string):Promise { @@ -60,9 +60,9 @@ export default class MP { .setTitle(DSS.server?.name.length > 0 ? DSS.server.name : 'Offline') .setColor(embedColor) .setDescription(DSS?.slots?.used < 1 ? '*Nobody is playing*' : players.join('\n\n')) - .setImage('attachment://'+attachmentName) + .setImage(`attachment://${attachmentName}`) .setAuthor({name: `${DSS.slots.used}/${DSS.slots.capacity}`}) - .setFooter({text: 'Current time: '+`${('0'+Math.floor((DSS?.server.dayTime/3600/1000))).slice(-2)}:${('0'+Math.floor((DSS?.server.dayTime/60/1000)%60)).slice(-2)}`}) + .setFooter({text: `Current time: ${('0'+Math.floor((DSS?.server.dayTime/3600/1000))).slice(-2)}:${('0'+Math.floor((DSS?.server.dayTime/60/1000)%60)).slice(-2)}`}) ], files: [new client.attachment(canvas.toBuffer(), {name: attachmentName})]}) }, details: async()=>{ @@ -73,7 +73,7 @@ export default class MP { const dEmbed = new client.embed().setColor(client.config.embedColor).setAuthor({name: 'Crossplay server'}).setDescription(MessageTool.concatMessage( `**Name:** \`${DSS?.server.name.length > 0 ? DSS.server.name : '\u200b'}\``, - `**Password:** \`mf4700\``, + '**Password:** `mf4700`', `**Map:** \`${DSS.server.mapName.length > 0 ? DSS.server.mapName : 'No map'}\``, `**Mods:** [Click here](http://${server.ip}/mods.html) **|** [Direct link](http://${server.ip}/all_mods_download?onlyActive=true)`, '**Filters:** [Click here](https://discord.com/channels/468835415093411861/468835769092669461/926581585938120724)', diff --git a/src/commands/purge.ts b/src/commands/purge.ts index 0f6a73f..6b0a5b5 100644 --- a/src/commands/purge.ts +++ b/src/commands/purge.ts @@ -7,7 +7,7 @@ export default class Purge { 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}) const user = interaction.options.getUser('user'); - let messagesArray: Array = []; + let messagesArray:string[] = []; if (user){ (interaction.channel as Discord.TextChannel).messages.fetch({limit: amount}).then(msgs=>{ diff --git a/src/commands/statistics.ts b/src/commands/statistics.ts index c4baa30..03b5fde 100644 --- a/src/commands/statistics.ts +++ b/src/commands/statistics.ts @@ -6,7 +6,7 @@ import GitHub from '../helpers/GitHub.js'; import si from 'systeminformation'; import os from 'node:os'; import ts from 'typescript'; -import {readFileSync} from 'fs'; +import {readFileSync} from 'node:fs'; export default class Statistics { static async run(client:TClient, interaction:Discord.ChatInputCommandInteraction<'cached'>) { const initialMsg = await interaction.reply({content: '', fetchReply:true}); diff --git a/src/commands/whois.ts b/src/commands/whois.ts index af34016..7513ebb 100644 --- a/src/commands/whois.ts +++ b/src/commands/whois.ts @@ -44,8 +44,8 @@ export default class Whois { {name: `🔹 Roles: ${member.roles.cache.size - 1}`, value: member.roles.cache.size > 1 ? member.roles.cache.filter(x=>x.id !== interaction.guild.roles.everyone.id).sort((a,b)=>b.position - a.position).map(x=>x).join(member.roles.cache.size > 4 ? ' ' : '\n').slice(0,1024) : 'No roles'} ) if (member.premiumSinceTimestamp !== null) embed.addFields({name: '🔹 Server Boosting since', value: `\n`, inline: true}) - if (!presence) embed.addFields({name: `🔹 Status: ⚫`, value: '\u200b'}) - if (member.presence) embed.addFields({name: `🔹 Status:`, value: `${member.presence.status === 'offline' ? '⚫' : `Desktop: ${convert(presence.desktop)}\nWeb: ${convert(presence.web)}\nMobile: ${convert(presence.mobile)}`}`, inline: true}) + if (!presence) embed.addFields({name: '🔹 Status: ⚫', value: '\u200b'}) + if (member.presence) embed.addFields({name: '🔹 Status:', value: `${member.presence.status === 'offline' ? '⚫' : `Desktop: ${convert(presence.desktop)}\nWeb: ${convert(presence.web)}\nMobile: ${convert(presence.mobile)}`}`, inline: true}) embedArray.push(embed) if (member.presence?.activities.find(a=>a.type === 2)) { const spotifyStatus = member.presence?.activities.find(a=>a.name === 'Spotify') as Discord.Activity; diff --git a/src/components/CanvasGraph.ts b/src/components/CanvasGraph.ts index e014e32..967b6ca 100644 --- a/src/components/CanvasGraph.ts +++ b/src/components/CanvasGraph.ts @@ -1,5 +1,5 @@ import {createCanvas, Canvas, CanvasRenderingContext2D} from 'canvas'; -import {Config} from '../interfaces'; +import {Config} from 'src/interfaces'; import ConfigHelper from '../helpers/ConfigHelper.js'; export default class CanvasBuilder { private canvas: Canvas; diff --git a/src/events/guildBanAdd.ts b/src/events/guildBanAdd.ts index 75d29d0..529bd51 100644 --- a/src/events/guildBanAdd.ts +++ b/src/events/guildBanAdd.ts @@ -1,9 +1,9 @@ -import Discord, { AuditLogEvent } from 'discord.js'; +import Discord from 'discord.js'; import TClient from '../client.js'; export default class GuildBanAdd { static async run(client:TClient, member:Discord.GuildMember){ if (member.guild?.id != client.config.dcServer.id) return; - const banLog = (await member.guild.fetchAuditLogs({ limit: 1, type: AuditLogEvent.MemberBanAdd })).entries.first(); + const banLog = (await member.guild.fetchAuditLogs({ limit: 1, type: Discord.AuditLogEvent.MemberBanAdd })).entries.first(); if (!banLog) return console.log(`Member was banned from ${member.guild.name} but no audit log for this member.`) const {executor, target, reason } = banLog; if (target.id === member.user.id) { diff --git a/src/events/guildBanRemove.ts b/src/events/guildBanRemove.ts index 50b27bd..f0dd1c0 100644 --- a/src/events/guildBanRemove.ts +++ b/src/events/guildBanRemove.ts @@ -1,9 +1,9 @@ -import Discord, { AuditLogEvent } from 'discord.js'; +import Discord from 'discord.js'; import TClient from '../client.js'; export default class GuildBanRemove { static async run(client:TClient, member:Discord.GuildMember){ if (member.guild?.id != client.config.dcServer.id) return; - const unbanLog = (await member.guild.fetchAuditLogs({limit: 1, type: AuditLogEvent.MemberBanRemove})).entries.first(); + const unbanLog = (await member.guild.fetchAuditLogs({limit: 1, type: Discord.AuditLogEvent.MemberBanRemove})).entries.first(); if (!unbanLog) return console.log(`User was unbanned from ${member.guild.name} but no audit log for this user.`) const { executor, target, reason } = unbanLog; if (target.id === member.user.id) (client.channels.resolve(client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds: [ diff --git a/src/events/messageDelete.ts b/src/events/messageDelete.ts index 65b7ae4..5ff14ad 100644 --- a/src/events/messageDelete.ts +++ b/src/events/messageDelete.ts @@ -1,7 +1,6 @@ import Discord from 'discord.js'; import TClient from '../client.js'; import Logger from '../helpers/Logger.js'; -import {escapeCodeBlock} from 'discord.js'; export default class MessageDelete { static run(client:TClient, msg:Discord.Message){ if (!client.config.botSwitches.logs) return; @@ -9,12 +8,12 @@ export default class MessageDelete { if (msg.guild?.id != client.config.dcServer.id || msg.partial || msg.author.bot || disabledChannels.includes(msg.channelId)) return; if (Discord.DiscordAPIError.name === '10008') return Logger.console('log', 'MsgDelete', 'Caught an unexpected error returned by Discord API. (Unknown Message)'); const embed = new client.embed().setColor(client.config.embedColorRed).setTimestamp().setAuthor({name: `Author: ${msg.author.username} (${msg.author.id})`, iconURL: `${msg.author.displayAvatarURL()}`}).setTitle('Message deleted').setDescription(`<@${msg.author.id}>\n\`${msg.author.id}\``); - if (msg.content.length != 0) embed.addFields({name: 'Content', value: `\`\`\`\n${escapeCodeBlock(msg.content.slice(0,1000))}\n\`\`\``}); + if (msg.content.length != 0) embed.addFields({name: 'Content', value: `\`\`\`\n${Discord.escapeCodeBlock(msg.content.slice(0,1000))}\n\`\`\``}); embed.addFields( { name: 'Channel', value: `<#${msg.channelId}>` }, { name: 'Sent at', value: `\n` } ) - const attachments: Array = []; + const attachments:string[] = []; msg.attachments.forEach(x=>attachments.push(x.url)); (client.channels.resolve(client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds: [embed], files: attachments}) } diff --git a/src/events/messageReactionAdd.ts b/src/events/messageReactionAdd.ts index e70364b..e47146d 100644 --- a/src/events/messageReactionAdd.ts +++ b/src/events/messageReactionAdd.ts @@ -6,6 +6,6 @@ export default class MessageReactionAdd { if (reaction.message.guildId != client.config.dcServer.id || reaction.message.partial) return; const ReactedFirst = reaction.users.cache.first(); if (ReactedFirst.id != user.id) return; - if (reaction.emoji.name === '🖕') return (client.channels.cache.get(client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds:[new client.embed().setColor(client.config.embedColorYellow).setTimestamp().setAuthor({name: `Author: ${ReactedFirst.username} (${ReactedFirst.id})`, iconURL: `${ReactedFirst.displayAvatarURL()}`}).setTitle('Message reaction').setDescription(`<@${ReactedFirst.id}>\nAdded a reaction to the message.\n**Emoji**\n${reaction.emoji.name}\n**Channel**\n<#${reaction.message.channelId}>`).setFooter({text: 'Possibly this member, bot fetches who reacted first.'})], components: [new Discord.ActionRowBuilder().addComponents(new Discord.ButtonBuilder().setStyle(5).setURL(`${reaction.message.url}`).setLabel('Jump to message'))]}); + if (reaction.emoji.name === '🖕') return (client.channels.cache.get(client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds:[new client.embed().setColor(client.config.embedColorYellow).setTimestamp().setAuthor({name: `Author: ${ReactedFirst.username} (${ReactedFirst.id})`, iconURL: ReactedFirst.displayAvatarURL()}).setTitle('Message reaction').setDescription(`<@${ReactedFirst.id}>\nAdded a reaction to the message.\n**Emoji**\n${reaction.emoji.name}\n**Channel**\n<#${reaction.message.channelId}>`).setFooter({text: 'Possibly this member, bot fetches who reacted first.'})], components: [new Discord.ActionRowBuilder().addComponents(new Discord.ButtonBuilder().setStyle(5).setURL(`${reaction.message.url}`).setLabel('Jump to message'))]}); } } diff --git a/src/events/messageReactionRemove.ts b/src/events/messageReactionRemove.ts index 88e23e6..c55f59b 100644 --- a/src/events/messageReactionRemove.ts +++ b/src/events/messageReactionRemove.ts @@ -3,6 +3,6 @@ import TClient from '../client.js'; export default class MessageReactionRemove { static run(client:TClient, reaction:Discord.MessageReaction, user:Discord.User){ if (!client.config.botSwitches.logs || reaction.message.guildId != client.config.dcServer.id || reaction.message.partial) return; - if (reaction.emoji.name === '🖕') return (client.channels.cache.get(client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds:[new client.embed().setColor(client.config.embedColorRed).setTimestamp().setAuthor({name: `Author: ${user.username} (${user.id})`, iconURL: `${user.displayAvatarURL()}`}).setTitle('Message reaction').setDescription(`<@${user.id}>\nRemoved a reaction from the message.\n**Emoji**\n${reaction.emoji.name}\n**Channel**\n<#${reaction.message.channelId}>`)]}) + if (reaction.emoji.name === '🖕') return (client.channels.cache.get(client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds:[new client.embed().setColor(client.config.embedColorRed).setTimestamp().setAuthor({name: `Author: ${user.username} (${user.id})`, iconURL: user.displayAvatarURL()}).setTitle('Message reaction').setDescription(`<@${user.id}>\nRemoved a reaction from the message.\n**Emoji**\n${reaction.emoji.name}\n**Channel**\n<#${reaction.message.channelId}>`)]}) } } diff --git a/src/events/messageUpdate.ts b/src/events/messageUpdate.ts index aa46d7c..c5db212 100644 --- a/src/events/messageUpdate.ts +++ b/src/events/messageUpdate.ts @@ -1,13 +1,12 @@ import Discord from 'discord.js'; import TClient from '../client.js'; import MessageTool from '../helpers/MessageTool.js'; -import {escapeCodeBlock} from 'discord.js'; export default class MessageUpdate { static async run(client:TClient, oldMsg:Discord.Message, newMsg:Discord.Message){ if (!client.config.botSwitches.logs) return; if (oldMsg.guild?.id != client.config.dcServer.id || oldMsg.author === null || oldMsg?.author.bot || oldMsg.partial || newMsg.partial || !newMsg.member || ['548032776830582794', '541677709487505408', '949380187668242483'].includes(newMsg.channelId)) return; if (await client.prohibitedWords.findWord(newMsg.content.toLowerCase().replaceAll(/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?\n?0-9]|[]|ing\b/g, '').split(' ').join('')) && (!MessageTool.isStaff(newMsg.member))) newMsg.delete(); if (newMsg.content === oldMsg.content) return; - (client.channels.resolve(client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds: [new client.embed().setColor(client.config.embedColor).setTimestamp().setAuthor({name: `Author: ${oldMsg.author.username} (${oldMsg.author.id})`, iconURL: `${oldMsg.author.displayAvatarURL()}`}).setTitle('Message edited').setDescription(`<@${oldMsg.author.id}>\nOld content:\n\`\`\`\n${oldMsg.content.length < 1 ? '(Attachment)' : escapeCodeBlock(oldMsg.content.slice(0,2048))}\n\`\`\`\nNew content:\n\`\`\`\n${escapeCodeBlock(newMsg.content.slice(0,2048))}\`\`\`\nChannel: <#${oldMsg.channelId}>`)], components: [new Discord.ActionRowBuilder().addComponents(new Discord.ButtonBuilder().setStyle(5).setURL(`${oldMsg.url}`).setLabel('Jump to message'))]}); + (client.channels.resolve(client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds: [new client.embed().setColor(client.config.embedColor).setTimestamp().setAuthor({name: `Author: ${oldMsg.author.username} (${oldMsg.author.id})`, iconURL: oldMsg.author.displayAvatarURL()}).setTitle('Message edited').setDescription(`<@${oldMsg.author.id}>\nOld content:\n\`\`\`\n${oldMsg.content.length < 1 ? '(Attachment)' : Discord.escapeCodeBlock(oldMsg.content.slice(0,2048))}\n\`\`\`\nNew content:\n\`\`\`\n${Discord.escapeCodeBlock(newMsg.content.slice(0,2048))}\`\`\`\nChannel: <#${oldMsg.channelId}>`)], components: [new Discord.ActionRowBuilder().addComponents(new Discord.ButtonBuilder().setStyle(5).setURL(`${oldMsg.url}`).setLabel('Jump to message'))]}); } } diff --git a/src/helpers/ConfigHelper.ts b/src/helpers/ConfigHelper.ts index 856ced5..4dea94b 100644 --- a/src/helpers/ConfigHelper.ts +++ b/src/helpers/ConfigHelper.ts @@ -1,5 +1,5 @@ import {readFileSync} from 'node:fs'; -import {Config} from '../interfaces'; +import {Config} from 'src/interfaces'; export default class ConfigHelper { static loadConfig() { let importconfig:Config; diff --git a/src/helpers/PalletLibrary.ts b/src/helpers/PalletLibrary.ts index b4e5182..4662af7 100644 --- a/src/helpers/PalletLibrary.ts +++ b/src/helpers/PalletLibrary.ts @@ -1,4 +1,4 @@ -import {FSData} from '../interfaces'; +import {FSData} from 'src/interfaces'; export default function(data:FSData) { const pallets = data.vehicles.filter(x=>x.category === 'PALLETS'); diff --git a/src/index.ts b/src/index.ts index c008a16..45e97cf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,7 +6,7 @@ import Logger from './helpers/Logger.js'; import YTModule from './modules/YTModule.js'; import MPModule, {refreshTimerSecs} from './modules/MPModule.js'; import UsernameHelper from './helpers/UsernameHelper.js'; -import {Punishment} from './interfaces'; +import {Punishment} from 'src/interfaces'; import {readFileSync} from 'node:fs'; // Error handler @@ -21,7 +21,7 @@ process.on('error', (error: Error)=>_(error, 'processError')); client.on('error', (error: Error)=>_(error, 'clientError')); // Interval timers for modules -setInterval(async()=>await MPModule(client), refreshTimerSecs); // Second param got moved to inside MPModule function to reduce the amount of failure rates. +setInterval(async()=>await MPModule(client), refreshTimerSecs); setInterval(()=>YTModule(client), 180000); // 3 minutes // Event loop for punishments and daily msgs diff --git a/src/models/punishments.ts b/src/models/punishments.ts index 7262d30..e8b9307 100644 --- a/src/models/punishments.ts +++ b/src/models/punishments.ts @@ -1,7 +1,7 @@ import Discord from 'discord.js'; import TClient from '../client.js'; import ms from 'ms'; -import {Punishment} from '../interfaces'; +import {Punishment} from 'src/interfaces'; import DatabaseServer from '../components/DatabaseServer.js'; import {Model, DataTypes} from 'sequelize'; import CacheServer from '../components/CacheServer.js'; @@ -119,7 +119,7 @@ export class PunishmentsSvc { `**${member.user.username}** (\`${member.user.id}\`) has been detected for case evasion.`, 'Timeout has been automatically added. (25 days)' )).setTimestamp()]}); - await this.punishmentAdd('mute', {time: '25d'}, this.client.user.id, '[AUTOMOD] Case evasion', member.user, member) + await this.punishmentAdd('mute', {time: '25d'}, this.client.user.id, 'AUTOMOD:Case evasion', member.user, member) } } async findInCache():Promise { @@ -134,7 +134,7 @@ export class PunishmentsSvc { return result; } async createModlog(punishment:Punishment) { - const channel = ['kick', 'ban', 'softban'].includes(punishment.type) ? this.client.config.dcServer.channels.bankick_log : this.client.config.dcServer.channels.logs; + const channel = ['kick', 'ban'].includes(punishment.type) ? this.client.config.dcServer.channels.bankick_log : this.client.config.dcServer.channels.logs; const embed = new this.client.embed() .setColor(this.client.config.embedColor) .setTitle(`${punishment.type[0].toUpperCase() + punishment.type.slice(1)} | Case #${punishment.case_id}`) diff --git a/src/modules/MPModule.ts b/src/modules/MPModule.ts index 87f1aca..8fe6a0e 100644 --- a/src/modules/MPModule.ts +++ b/src/modules/MPModule.ts @@ -6,7 +6,7 @@ import FormatPlayer from '../helpers/FormatPlayer.js'; import Logger from '../helpers/Logger.js'; import HookMgr from '../components/HookManager.js'; import {IServer} from '../models/MPServer.js'; -import {FSPlayer, FSData, FSCareerSavegame} from '../interfaces.js'; +import {FSPlayer, FSData, FSCareerSavegame} from 'src/interfaces'; let loggingPrefix:string = 'MPModule'; let dataUnavailable:string = 'Unavailable';