From ade8f53d08dcbe4529976e6e6c6faeadbb916c86 Mon Sep 17 00:00:00 2001 From: toast-ts <96593068+toast-ts@users.noreply.github.com> Date: Sat, 6 May 2023 08:41:35 +1000 Subject: [PATCH] Move MP Loop to its own house and improved it a bit. --- src/MPLoop.ts | 89 ++++++++++++++++++++++++++++++++++ src/config.json | 4 ++ src/index.ts | 95 ++----------------------------------- src/typings/interfaces.d.ts | 5 ++ 4 files changed, 101 insertions(+), 92 deletions(-) create mode 100644 src/MPLoop.ts diff --git a/src/MPLoop.ts b/src/MPLoop.ts new file mode 100644 index 0000000..21d6301 --- /dev/null +++ b/src/MPLoop.ts @@ -0,0 +1,89 @@ +import Discord from 'discord.js'; +import TClient from './client'; +import fs from 'node:fs'; +import {FSData, FSCareerSavegame} from './typings/interfaces'; + +export default async(client:TClient,Channel:string,Message:string)=>{ + if (!client.config.botSwitches.mpstats) return; + const msg = await (client.channels.resolve(Channel) as Discord.TextChannel).messages.fetch(Message); + const embed = new client.embed(); + let Players = []; + let error:Boolean; + + const Server = await client.MPServer._content.findById(client.config.mainServer.id); + const FS_IP = Server.ip; + const FS_Code = Server.code; + const verifyUrl = FS_IP.match(/http|https/); + const DSSUrl = FS_IP+'/feed/dedicated-server-stats.json?code='+FS_Code; + const CSGUrl = FS_IP+'/feed/dedicated-server-savegame.html?code='+FS_Code+'&file=careerSavegame'; + + const DSS = { + data: {} as FSData, fetchResult: '' as string + }; + const CSG = { + data: {} as FSCareerSavegame, fetchResult: '' as string + }; + + if (!verifyUrl) return msg.edit({content: '*Detected an invalid IP\nContact MP Manager or Bot Tech*', embeds: null}); + async function serverData(client:TClient, URL:string){ + return await client.axios.get(URL, {timeout: 5000, maxContentLength: Infinity, headers:{'User-Agent':`Daggerbot/axios ${client.axios.VERSION}`}}).catch((error:Error)=>error.message) + } + await Promise.all([serverData(client, DSSUrl), serverData(client, CSGUrl)]).then(function(results){ + if (typeof results[0] === 'string'){ + DSS.fetchResult = `DagMP DSS failed, ${results[0]}`; + embed.addFields({name:'DSS Status',value:results[0]}) + } else if (results[0].status != 200){ + DSS.fetchResult = `DagMP DSS failed with ${results[0].status + ' ' + results[0].statusText}`; + embed.addFields({name:'DSS Status',value:results[0].status + ' ' + results[0].statusText}) + } else DSS.data = results[0].data as FSData + + if (typeof results[1] === 'string'){ + CSG.fetchResult = `DagMP CSG failed, ${results[1]}`; + embed.addFields({name:'CSG Status',value:results[1]}) + } else if (results[1].status != 200){ + if (results[1].status === 204) embed.setImage('https://http.cat/204'); + CSG.fetchResult = `DagMP CSG failed with ${results[1].status + ' ' + results[1].statusText}`; + embed.addFields({name:'CSG Status',value:results[1].status + ' ' + results[1].statusText}) + } else CSG.data = (client.xjs.xml2js(results[1].data,{compact:true}) as any).careerSavegame as FSCareerSavegame + }).catch(error=>console.error(error)); + + if (DSS.fetchResult.length != 0){ + error = true; + if (DSS.data.slots === undefined) return; + console.error(client.logTime(), DSS.fetchResult); + } else if (CSG.fetchResult.length != 0){ + error = true; + console.error(client.logTime(), CSG.fetchResult); + } + if (error){ // Blame Nawdic + embed.setTitle('Host is not responding').setColor(client.config.embedColorRed); + msg.edit({content:null, embeds: [embed]}) + return; + } + + const Database = JSON.parse(fs.readFileSync('src/database/MPPlayerData.json',{encoding:'utf8',flag:'r+'})); + Database.push(DSS.data.slots?.used); + fs.writeFileSync('src/database/MPPlayerData.json', JSON.stringify(Database)); + + //Timescale formatting + function formatTimescale(number:number,digits:number,icon:string){ + var n = Number(number); + return n.toLocaleString(undefined, {minimumFractionDigits: digits})+icon + } + + if (DSS.data.server.name.length === 0){ + embed.setTitle('The server seems to be offline.').setColor(client.config.embedColorRed); + msg.edit({content: 'This embed will resume when the server is back online.', embeds: [embed]}) + } else { + const statusEmbed = new client.embed().setColor(client.config.embedColor).setTitle('Server details').setFields( + {name: 'Current Map', value: `${DSS.data.server.mapName.length === 0 ? '\u200b' : DSS.data.server.mapName}`, inline: true}, + {name: 'Version', value: `${DSS.data.server.version.length === 0 ? '\u200b' : DSS.data.server.version}`, inline: true}, + {name: 'In-game Time', value: `${('0'+Math.floor((DSS.data.server.dayTime/3600/1000))).slice(-2)}:${('0'+Math.floor((DSS.data.server.dayTime/60/1000)%60)).slice(-2)}`, inline: true}, + {name: 'Slot Usage', value: `${isNaN(Number(CSG.data.slotSystem?._attributes.slotUsage)) === true ? 'Unavailable' : Number(CSG.data.slotSystem?._attributes.slotUsage).toLocaleString('en-us')}`, inline: true}, + {name: 'Timescale', value: `${isNaN(Number(CSG.data.settings?.timeScale._text)) === true ? 'Unavailable' : formatTimescale(Number(CSG.data.settings?.timeScale._text), 0, 'x')}`, inline: true} + ); + DSS.data.slots.players.filter(x=>x.isUsed !== false).forEach(player=>Players.push(`**${player.name} ${player.isAdmin ? '| admin' : ''}**\nFarming for ${(Math.floor(player.uptime/60))} hr & ${(''+(player.uptime%60)).slice(-2)} min`)); + embed.setColor(client.config.embedColor).setTitle(DSS.data.server.name).setDescription(`${DSS.data.slots.used === 0 ? '*No players online*' : Players.join('\n\n')}`).setAuthor({name:`${DSS.data.slots.used}/${DSS.data.slots.capacity}`}); + msg.edit({content:'This embed updates every minute.',embeds:[statusEmbed,embed]}) + } +} diff --git a/src/config.json b/src/config.json index c02d469..5427bf5 100644 --- a/src/config.json +++ b/src/config.json @@ -10,6 +10,10 @@ "whitelistedServers": [ "929807948748832798", "468835415093411861", "1058183358267543552" ], + "MPStatsLocation": { + "channel": "543494084363288637", + "message": "1023699243183112192" + }, "botSwitches": { "registerCommands": true, "commands": true, diff --git a/src/index.ts b/src/index.ts index fcaafba..68cd7f4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,8 +2,8 @@ import Discord from 'discord.js'; import TClient from './client.js'; const client = new TClient; client.init(); +import MPLoop from './MPLoop.js'; import fs from 'node:fs'; -import {FSData, FSCareerSavegame} from './typings/interfaces'; client.on('ready', async()=>{ setInterval(()=>client.user.setPresence(client.config.botPresence), 300000); @@ -35,97 +35,8 @@ process.on('uncaughtException', (error: Error)=>DZ(error, 'uncaughtException')); process.on('error', (error: Error)=>DZ(error, 'process-error')); client.on('error', (error: Error)=>DZ(error, 'client-error')); -// Daggerwin MP loop -setInterval(async()=>{ - if (!client.config.botSwitches.mpstats) return; - const msg = await (client.channels.resolve('543494084363288637') as Discord.TextChannel).messages.fetch('1023699243183112192') - const embed = new client.embed(); - let Players = []; - let error; - - // Connect to DB to retrieve the Gameserver info to fetch data. - const ServerURL = await client.MPServer._content.findById(client.config.mainServer.id); - const MPURL = ServerURL.ip; - const MPCode = ServerURL.code; - const verifyURL = MPURL.match(/http|https/); - const completedURL_DSS = MPURL+'/feed/dedicated-server-stats.json?code='+MPCode; - const completedURL_CSG = MPURL+'/feed/dedicated-server-savegame.html?code='+MPCode+'&file=careerSavegame'; - const FSdss = { - data: {} as FSData, - fetchResult: '' as string - }; - const FScsg = { - data: {} as FSCareerSavegame, - fetchResult: '' as string - }; - if (!verifyURL) return msg.edit({content: '*Detected an invalid IP.*', embeds: null}) - async function serverData(client:TClient, URL: string){ - return await client.axios.get(URL, {timeout: 4000, maxContentLength: Infinity, headers: {'User-Agent': `Daggerbot/axios ${client.axios.VERSION}`}}).catch((error:Error)=>error.message) - } - await Promise.all([serverData(client, completedURL_DSS), serverData(client, completedURL_CSG)]).then(function(results){ - if (typeof results[0] == 'string'){ - FSdss.fetchResult = `DagMP DSS failed, ${results[0]}`; - embed.addFields({name: 'DSS Status', value: results[0]}) - } else if (results[0].status != 200){ - FSdss.fetchResult = `DagMP DSS failed with ${results[0].status + ' ' + results[0].statusText}`; - embed.addFields({name: 'DSS Status', value: results[0].status + ' ' + results[0].statusText}) - } else FSdss.data = results[0].data as FSData - - if (typeof results[1] == 'string'){ - FScsg.fetchResult = `DagMP CSG failed, ${results[1]}`; - embed.addFields({name: 'CSG Status', value: results[1]}) - } else if (results[1].status != 200){ - if (results[1].status == 204) embed.setImage('https://http.cat/204'); - FScsg.fetchResult = `DagMP CSG failed with ${results[1].status + ' ' + results[1].statusText}`; - embed.addFields({name: 'CSG Status', value: results[1].status + ' ' + results[1].statusText}) - } else FScsg.data = (client.xjs.xml2js(results[1].data,{compact:true}) as any).careerSavegame as FSCareerSavegame; - }).catch((error)=>console.log(error)) - if (FSdss.fetchResult.length != 0){ - error = true; - if (FSdss.data.slots === undefined) return; - console.log(client.logTime(), FSdss.fetchResult); - } - if (FScsg.fetchResult.length != 0){ - error = true; - console.log(client.logTime(), FScsg.fetchResult); - } - if (error) { // Blame RedRover and Nawdic - embed.setTitle('Host is not responding').setColor(client.config.embedColorRed); - msg.edit({content: null, embeds: [embed]}) - return; - } - - const DB = JSON.parse(fs.readFileSync('src/database/MPPlayerData.json', {encoding: 'utf8'})); - DB.push(FSdss.data.slots.used) - fs.writeFileSync('src/database/MPPlayerData.json', JSON.stringify(DB)) - - // Number format function - function formatNumber(number: any, digits: any, icon: any){ - var n = Number(number) - return n.toLocaleString(undefined, {minimumFractionDigits: digits})+icon - } // Temporary workaround for fresh save. - const slotSystem = isNaN(Number(FScsg.data.slotSystem?._attributes.slotUsage)) == true ? 'Unavailable' : Number(FScsg.data.slotSystem?._attributes.slotUsage).toLocaleString('en-US'); - const timeScale = isNaN(Number(FScsg.data.settings?.timeScale._text)) == true ? 'Unavailable' : formatNumber(Number(FScsg.data.settings?.timeScale._text), 0, 'x'); - - if (FSdss.data.server.name.length == 0){ - embed.setTitle('The server seems to be offline.').setColor(client.config.embedColorRed); - msg.edit({content: 'This embed will resume when server is back online.', embeds: [embed]}) - } else { - const embed1 = new client.embed().setColor(client.config.embedColor).setTitle('Server details').addFields( - {name: 'Current Map', value: `${FSdss.data.server.mapName.length == 0 ? '\u200b' : FSdss.data.server.mapName}`, inline: true}, - {name: 'Version', value: `${FSdss.data.server.version.length == 0 ? '\u200b' : FSdss.data.server.version}`, inline: true}, - {name: 'In-game Time', value: `${('0' + Math.floor((FSdss.data.server.dayTime/3600/1000))).slice(-2)}:${('0' + Math.floor((FSdss.data.server.dayTime/60/1000)%60)).slice(-2)}`, inline: true}, - {name: 'Slot Usage', value: `${slotSystem}`, inline: true}, - {name: 'Timescale', value: `${timeScale}`, inline: true} - ); - FSdss.data.slots.players.filter((x)=>x.isUsed !== false).forEach(player=>Players.push(`**${player.name} ${player.isAdmin ? '| admin' : ''}**\nFarming for ${(Math.floor(player.uptime/60))} hr & ${('' + (player.uptime % 60)).slice(-2)} min`)) - embed.setDescription(`${FSdss.data.slots.used == 0 ? '*No players online*' : Players.join('\n\n')}`).setTitle(FSdss.data.server.name).setColor(client.config.embedColor) - embed.setAuthor({name: `${FSdss.data.slots.used}/${FSdss.data.slots.capacity}`}); - msg.edit({content: 'This embed updates every minute.', embeds: [embed1, embed]}) - } -}, 60000) - -// YouTube Upload notification +// YouTube Upload notification and Daggerwin MP loop +setInterval(()=>MPLoop(client, client.config.MPStatsLocation.channel, client.config.MPStatsLocation.message), 60000); setInterval(async()=>{ client.YTLoop('UCQ8k8yTDLITldfWYKDs3xFg', 'Daggerwin', '528967918772551702'); // 528967918772551702 = #videos-and-streams client.YTLoop('UCguI73--UraJpso4NizXNzA', 'Machinery Restorer', '767444045520961567') // 767444045520961567 = #machinery-restorer diff --git a/src/typings/interfaces.d.ts b/src/typings/interfaces.d.ts index 4fa71fe..cf03170 100644 --- a/src/typings/interfaces.d.ts +++ b/src/typings/interfaces.d.ts @@ -141,12 +141,17 @@ export interface Config { embedColorXmas: Discord.ColorResolvable, LRSstart: number, whitelistedServers: Array, + MPStatsLocation: MPStatsLocation, botSwitches: botSwitches, botPresence: Discord.PresenceData, eval: boolean, whitelist: Array mainServer: mainServer } +interface MPStatsLocation { + channel: string, + message: string +} interface botSwitches { registerCommands: boolean, commands: boolean,