From b9e7cfc3d4cc3a427a3690aee953f634e4734a4a Mon Sep 17 00:00:00 2001 From: toast-ts <96593068+toast-ts@users.noreply.github.com> Date: Thu, 5 Oct 2023 22:57:07 +1100 Subject: [PATCH] Improve codebase in various files --- src/events/guildMemberUpdate.ts | 8 +- src/events/messageDelete.ts | 4 +- src/events/messageUpdate.ts | 3 +- src/funcs/Automod.ts | 2 +- src/funcs/MPModule.ts | 145 +++++++++++++++----------------- 5 files changed, 79 insertions(+), 83 deletions(-) diff --git a/src/events/guildMemberUpdate.ts b/src/events/guildMemberUpdate.ts index 0841fc0..240e06b 100644 --- a/src/events/guildMemberUpdate.ts +++ b/src/events/guildMemberUpdate.ts @@ -6,16 +6,16 @@ export default { if (!client.config.botSwitches.logs) return; const channel = (client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel); if (oldMember.nickname != newMember.nickname){ - const embed = new client.embed().setColor(client.config.embedColor).setTimestamp().setThumbnail(newMember.user.displayAvatarURL({size: 2048})).setTitle(`Nickname updated: ${newMember.user.username}`).setDescription(`<@${newMember.user.id}>\n\`${newMember.user.id}\``) + const embed = new client.embed().setColor(client.config.embedColor).setTimestamp().setThumbnail(newMember.displayAvatarURL({size: 2048})).setTitle(`Nickname updated: ${newMember.user.username}`).setDescription(`<@${newMember.user.id}>\n\`${newMember.user.id}\``) oldMember.nickname === null ? '' : embed.addFields({name: '🔹 Old nickname', value: `\`\`\`${oldMember.nickname}\`\`\``}) newMember.nickname === null ? embed.setFooter({text:'Nickname has been reset.'}) : embed.addFields({name: '🔹 New nickname', value: `\`\`\`${newMember.nickname}\`\`\``}) channel.send({embeds: [embed]}) } - const newRoles = newMember.roles.cache.map((x,i)=>i).filter(x=>!oldMember.roles.cache.map((x,i)=>i).some(y=>y===x)); - const oldRoles = oldMember.roles.cache.map((x,i)=>i).filter(x=>!newMember.roles.cache.map((x,i)=>i).some(y=>y===x)); + const newRoles = newMember.roles.cache.map((_,i)=>i).filter(x=>!oldMember.roles.cache.map((_,i)=>i).some(y=>y===x)); + const oldRoles = oldMember.roles.cache.map((_,i)=>i).filter(x=>!newMember.roles.cache.map((_,i)=>i).some(y=>y===x)); if (newRoles.length === 0 && oldRoles.length == 0) return; - const embed = new client.embed().setColor(client.config.embedColor).setThumbnail(newMember.user.displayAvatarURL({size: 2048})).setTitle(`Role updated: ${newMember.user.username}`).setDescription(`<@${newMember.user.id}>\n\`${newMember.user.id}\``) + const embed = new client.embed().setColor(client.config.embedColor).setThumbnail(newMember.displayAvatarURL({size: 2048})).setTitle(`Role updated: ${newMember.user.username}`).setDescription(`<@${newMember.user.id}>\n\`${newMember.user.id}\``) if (newRoles.length != 0) embed.addFields({name: newRoles.length > 1 ? '🔹 Roles added' : '🔹 Role added', value: newRoles.map(x=>`<@&${x}>`).join(' ')}); if (oldRoles.length != 0) embed.addFields({name: oldRoles.length > 1 ? '🔹 Roles removed' : '🔹 Role removed', value: oldRoles.map(x=>`<@&${x}>`).join(' ')}); channel.send({embeds: [embed]}) diff --git a/src/events/messageDelete.ts b/src/events/messageDelete.ts index 604ecd9..a14422e 100644 --- a/src/events/messageDelete.ts +++ b/src/events/messageDelete.ts @@ -1,7 +1,7 @@ import Discord from 'discord.js'; import TClient from '../client.js'; import Logger from '../helpers/Logger.js'; - +import {escapeCodeBlock} from 'discord.js'; export default { run(client:TClient, msg:Discord.Message){ if (!client.config.botSwitches.logs) return; @@ -9,7 +9,7 @@ export default { if (msg.guild?.id != client.config.mainServer.id || msg.partial || msg.author.bot || disabledChannels.includes(msg.channelId)) return; if (Discord.DiscordAPIError.name === '10008') return Logger.forwardToConsole('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${msg.content.slice(0,1000)}\n\`\`\``}); + if (msg.content.length != 0) embed.addFields({name: 'Content', value: `\`\`\`\n${escapeCodeBlock(msg.content.slice(0,1000))}\n\`\`\``}); embed.addFields( { name: 'Channel', value: `<#${msg.channelId}>` }, { name: 'Sent at', value: `\n` } diff --git a/src/events/messageUpdate.ts b/src/events/messageUpdate.ts index 97ef122..cefe0ff 100644 --- a/src/events/messageUpdate.ts +++ b/src/events/messageUpdate.ts @@ -1,11 +1,12 @@ import Discord from 'discord.js'; import TClient from '../client.js'; +import {escapeCodeBlock} from 'discord.js'; export default { async run(client:TClient, oldMsg:Discord.Message, newMsg:Discord.Message){ if (!client.config.botSwitches.logs) return; if (oldMsg.guild?.id != client.config.mainServer.id || oldMsg.author === null || oldMsg?.author.bot || oldMsg.partial || newMsg.partial || !newMsg.member || ['548032776830582794', '541677709487505408', '949380187668242483'].includes(newMsg.channelId)) return; if (await client.bannedWords._content.findOne({_id:newMsg.content.toLowerCase().replaceAll(/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?\n]/g, ' ').split(' ')}) && (!client.isStaff(newMsg.member))) newMsg.delete(); if (newMsg.content === oldMsg.content) return; - (client.channels.resolve(client.config.mainServer.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)' : oldMsg.content}\n\`\`\`\nNew content:\n\`\`\`\n${newMsg.content}\`\`\`\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.mainServer.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'))]}); } } diff --git a/src/funcs/Automod.ts b/src/funcs/Automod.ts index 77854a6..39c6ce8 100644 --- a/src/funcs/Automod.ts +++ b/src/funcs/Automod.ts @@ -18,7 +18,7 @@ export default class Automoderator { client.repeatedMessages[message.author.id].timeout = setTimeout(()=>delete client.repeatedMessages[message.author.id], thresholdTime); // Message sent after (now - threshold), so purge those that were sent earlier - client.repeatedMessages[message.author.id].data = client.repeatedMessages[message.author.id].data.filter((x,i)=>i>=Date.now() - thresholdTime); + client.repeatedMessages[message.author.id].data = client.repeatedMessages[message.author.id].data.filter((_,i)=>i >= Date.now() - thresholdTime); // A spammed message is one that has been sent within the threshold parameters const spammedMessage = client.repeatedMessages[message.author.id].data.find(x=>{ diff --git a/src/funcs/MPModule.ts b/src/funcs/MPModule.ts index 7a280db..ac24350 100644 --- a/src/funcs/MPModule.ts +++ b/src/funcs/MPModule.ts @@ -10,86 +10,81 @@ import {writeFileSync, readFileSync} from 'node:fs'; import {FSPlayer, FSData, FSCareerSavegame} from '../typings/interfaces'; export default async(client:TClient, Channel:string, Message:string, Server:TServer, ServerName:string)=>{ - let isServerOnline = false; let playerData:Array = []; const msg = await (client.channels.resolve(Channel) as Discord.TextChannel).messages.fetch(Message); const serverErrorEmbed = new client.embed().setColor(client.config.embedColorRed).setTitle('Host did not respond back in time'); const genericEmbed = new client.embed(); + let sessionInit = {signal: AbortSignal.timeout(8500),headers:{'User-Agent':'Daggerbot - HITALL/undici'}}; + + try { + const hitDSS = await fetch(Server.ip+'/feed/dedicated-server-stats.json?code='+Server.code, sessionInit).then(r=>r.json() as Promise); + const hitCSG = await fetch(Server.ip+'/feed/dedicated-server-savegame.html?code='+Server.code+'&file=careerSavegame', sessionInit).then(async r=>(client.xjs.xml2js(await r.text(), {compact: true}) as any).careerSavegame as FSCareerSavegame); - const HITALL = async()=>{ - let sessionInit = {signal: AbortSignal.timeout(8200),headers:{'User-Agent':'Daggerbot - HITALL/undici'}}; - try { - const hitDSS = await fetch(Server.ip+'/feed/dedicated-server-stats.json?code='+Server.code, sessionInit).then(r=>r.json() as Promise); - const hitCSG = await fetch(Server.ip+'/feed/dedicated-server-savegame.html?code='+Server.code+'&file=careerSavegame', sessionInit).then(async r=>(client.xjs.xml2js(await r.text(), {compact: true}) as any).careerSavegame as FSCareerSavegame); - - if (!hitDSS ?? !hitCSG){ - if (hitDSS && !hitDSS.slots) return Logger.forwardToConsole('log', 'MPModule', `DSS failed with unknown slots table for ${client.MPServerCache[ServerName].name}`); - else return msg.edit({embeds: [serverErrorEmbed]}); - } - - // Truncate unnecessary parts of the name for the MPServerCache - // This is a mess, but it works. - for (const filter of ['Official Daggerwin Game Server', 'Daggerwin Multifarm']) { - if (hitDSS.server?.name === undefined) return; - if (hitDSS.server?.name.includes(filter)) client.MPServerCache[ServerName].name = ['Daggerwin', 'DagMF'][['Official Daggerwin Game Server', 'Daggerwin Multifarm'].indexOf(filter)]; - } - - //Timescale formatting - function formatTimescale(number:number,digits:number,icon:string){ - var n = Number(number); - return n.toLocaleString(undefined, {minimumFractionDigits: digits})+icon - } - - // Join/Leave log - function playerLogEmbed(player:FSPlayer,joinLog:boolean){ - const logEmbed = new client.embed().setDescription(`**${player.name}${FormatPlayer.decoratePlayerIcons(player)}** ${joinLog ? 'joined' : 'left'} **${client.MPServerCache[ServerName].name}** at `); - if (joinLog) return logEmbed.setColor(client.config.embedColorGreen); - else if (player.uptime > 0) return logEmbed.setColor(client.config.embedColorRed).setFooter({text:`Farmed for ${FormatPlayer.uptimeFormat(player.uptime)}`}); - else return logEmbed.setColor(client.config.embedColorRed); - } - - const serverLog = client.channels.resolve(client.config.mainServer.channels.fs_server_log) as Discord.TextChannel; - const playersOnServer = hitDSS.slots?.players.filter(x=>x.isUsed); - const playersInCache = client.MPServerCache[ServerName].players; - if (!playersOnServer ?? playersOnServer === undefined) return Logger.forwardToConsole('log', 'MPModule', 'Array is empty, ignoring...'); // For the love of god, stop throwing errors everytime. - playersOnServer.forEach(player=>playerData.push(`**${player.name}${FormatPlayer.decoratePlayerIcons(player)}**\nFarming for ${FormatPlayer.uptimeFormat(player.uptime)}`)); - - // Player leaving - for (const player of playersInCache.filter(x=>!playersOnServer.some(y=>y.name === x.name))){ - if (player.uptime > 0) serverLog.send({embeds:[playerLogEmbed(player,false)]}); - } // Player joining - let playerObject; - if (!playersInCache.length && client.uptime > 32010) playerObject = playersOnServer; - if (playerObject) for (const player of playerObject) serverLog.send({embeds:[playerLogEmbed(player,true)]}); - else if (playersInCache.length) playerObject = playersOnServer.filter(x=>!playersInCache.some(y=>y.name === x.name)); - - if (client.MPServerCache[ServerName].name === null) return; - const Database:Array = JSON.parse(readFileSync(`src/database/${client.MPServerCache[ServerName].name}PlayerData.json`,{encoding:'utf8',flag:'r+'})); - Database.push(hitDSS.slots?.used); - writeFileSync(`src/database/${client.MPServerCache[ServerName].name}PlayerData.json`, JSON.stringify(Database)); - client.MPServerCache[ServerName].players = playersOnServer; - - if (hitDSS.server.name.length < 1) { - msg.edit({content: 'This embed will resume when server is back online.', embeds: [genericEmbed.setColor(client.config.embedColorRed).setTitle('The server seems to be offline.')]}); - client.MPServerCache[ServerName].status = 'offline' - } else { - isServerOnline = true; - client.MPServerCache[ServerName].status = 'online'; - const serverDetails = new client.embed().setColor(client.config.embedColor).setTitle('Server details').setFields( - {name: 'Current map', value: hitDSS.server.mapName, inline: true}, - {name: 'Server version', value: hitDSS.server.version, inline: true}, - {name: 'In-game Time', value: `${('0'+Math.floor((hitDSS.server.dayTime/3600/1000))).slice(-2)}:${('0'+Math.floor((hitDSS.server.dayTime/60/1000)%60)).slice(-2)}`, inline: true}, - {name: 'Slot Usage', value: isNaN(Number(hitCSG?.slotSystem?._attributes.slotUsage)) === true ? 'Unavailable' : Number(hitCSG.slotSystem?._attributes.slotUsage).toLocaleString('en-us'), inline: true}, - {name: 'Autosave Interval', value: isNaN(Number(hitCSG?.settings?.autoSaveInterval._text)) === true ? 'Unavailable' : Number(hitCSG.settings?.autoSaveInterval._text).toFixed(0)+' mins', inline:true}, - {name: 'Timescale', value: isNaN(Number(hitCSG?.settings?.timeScale._text)) === true ? 'Unavailable' : formatTimescale(Number(hitCSG.settings?.timeScale._text), 0, 'x'), inline: true} - ); - const playersEmbed = new client.embed().setColor(client.config.embedColor).setTitle(hitDSS.server.name).setDescription(hitDSS.slots.used < 1 ? '*No players online*' : playerData.join('\n\n')).setAuthor({name:`${hitDSS.slots.used}/${hitDSS.slots.capacity}`}); - msg.edit({content:'This embed updates every 35 seconds.',embeds:[serverDetails, playersEmbed]}); - } - } catch(err) { - msg.edit({content: err.message, embeds: [serverErrorEmbed]}); - Logger.forwardToConsole('log', 'MPModule', `Failed to make a request for ${ServerName}: ${err.message}`); + if (!hitDSS ?? !hitCSG){ + if (hitDSS && !hitDSS.slots) return Logger.forwardToConsole('log', 'MPModule', `DSS failed with unknown slots table for ${client.MPServerCache[ServerName].name}`); + else return msg.edit({embeds: [serverErrorEmbed]}); } + + // Truncate unnecessary parts of the name for the MPServerCache + // This is a mess, but it works. + for (const filter of ['Official Daggerwin Game Server', 'Daggerwin Multifarm']) { + if (hitDSS.server?.name === undefined) return; + if (hitDSS.server?.name.includes(filter)) client.MPServerCache[ServerName].name = ['Daggerwin', 'DagMF'][['Official Daggerwin Game Server', 'Daggerwin Multifarm'].indexOf(filter)]; + } + + //Timescale formatting + function formatTimescale(number:number,digits:number,icon:string){ + var n = Number(number); + return n.toLocaleString(undefined, {minimumFractionDigits: digits})+icon + } + + // Join/Leave log + function playerLogEmbed(player:FSPlayer,joinLog:boolean){ + const logEmbed = new client.embed().setDescription(`**${player.name}${FormatPlayer.decoratePlayerIcons(player)}** ${joinLog ? 'joined' : 'left'} **${client.MPServerCache[ServerName].name}** at `); + if (joinLog) return logEmbed.setColor(client.config.embedColorGreen); + else if (player.uptime > 0) return logEmbed.setColor(client.config.embedColorRed).setFooter({text:`Farmed for ${FormatPlayer.uptimeFormat(player.uptime)}`}); + else return logEmbed.setColor(client.config.embedColorRed); + } + + const serverLog = client.channels.resolve(client.config.mainServer.channels.fs_server_log) as Discord.TextChannel; + const playersOnServer = hitDSS.slots?.players.filter(x=>x.isUsed); + const playersInCache = client.MPServerCache[ServerName].players; + if (!playersOnServer ?? playersOnServer === undefined) return Logger.forwardToConsole('log', 'MPModule', 'Array is empty, ignoring...'); // For the love of god, stop throwing errors everytime. + playersOnServer.forEach(player=>playerData.push(`**${player.name}${FormatPlayer.decoratePlayerIcons(player)}**\nFarming for ${FormatPlayer.uptimeFormat(player.uptime)}`)); + + // Player leaving + for (const player of playersInCache.filter(x=>!playersOnServer.some(y=>y.name === x.name))){ + if (player.uptime > 0) serverLog.send({embeds:[playerLogEmbed(player,false)]}); + } // Player joining + let playerObject; + if (!playersInCache.length && client.uptime > 32010) playerObject = playersOnServer; + if (playerObject) for (const player of playerObject) serverLog.send({embeds:[playerLogEmbed(player,true)]}); + else if (playersInCache.length) playerObject = playersOnServer.filter(x=>!playersInCache.some(y=>y.name === x.name)); + + if (client.MPServerCache[ServerName].name === null) return; + const Database:Array = JSON.parse(readFileSync(`src/database/${client.MPServerCache[ServerName].name}PlayerData.json`,{encoding:'utf8',flag:'r+'})); + Database.push(hitDSS.slots?.used); + writeFileSync(`src/database/${client.MPServerCache[ServerName].name}PlayerData.json`, JSON.stringify(Database)); + client.MPServerCache[ServerName].players = playersOnServer; + + if (hitDSS.server.name.length < 1) { + msg.edit({content: 'This embed will resume when server is back online.', embeds: [genericEmbed.setColor(client.config.embedColorRed).setTitle('The server seems to be offline.')]}); + client.MPServerCache[ServerName].status = 'offline' + } else { + client.MPServerCache[ServerName].status = 'online'; + const serverDetails = new client.embed().setColor(client.config.embedColor).setTitle('Server details').setFields( + {name: 'Current map', value: hitDSS.server.mapName, inline: true}, + {name: 'Server version', value: hitDSS.server.version, inline: true}, + {name: 'In-game Time', value: `${('0'+Math.floor((hitDSS.server.dayTime/3600/1000))).slice(-2)}:${('0'+Math.floor((hitDSS.server.dayTime/60/1000)%60)).slice(-2)}`, inline: true}, + {name: 'Slot Usage', value: isNaN(Number(hitCSG?.slotSystem?._attributes.slotUsage)) === true ? 'Unavailable' : Number(hitCSG.slotSystem?._attributes.slotUsage).toLocaleString('en-us'), inline: true}, + {name: 'Autosave Interval', value: isNaN(Number(hitCSG?.settings?.autoSaveInterval._text)) === true ? 'Unavailable' : Number(hitCSG.settings?.autoSaveInterval._text).toFixed(0)+' mins', inline:true}, + {name: 'Timescale', value: isNaN(Number(hitCSG?.settings?.timeScale._text)) === true ? 'Unavailable' : formatTimescale(Number(hitCSG.settings?.timeScale._text), 0, 'x'), inline: true} + ); + const playersEmbed = new client.embed().setColor(client.config.embedColor).setTitle(hitDSS.server.name).setDescription(hitDSS.slots.used < 1 ? '*No players online*' : playerData.join('\n\n')).setAuthor({name:`${hitDSS.slots.used}/${hitDSS.slots.capacity}`}); + msg.edit({content:'This embed updates every 35 seconds.',embeds:[serverDetails, playersEmbed]}); + } + } catch(err) { + msg.edit({content: err.message, embeds: [serverErrorEmbed]}); + Logger.forwardToConsole('log', 'MPModule', `Failed to make a request for ${ServerName}: ${err.message}`); } - HITALL(); }