2023-09-01 00:32:11 -04:00
interface TServer {
ip : string
code : string
}
2023-05-05 18:41:35 -04:00
import Discord from 'discord.js' ;
2023-09-03 00:15:02 -04:00
import TClient from '../client.js' ;
2023-08-30 04:34:59 -04:00
import FormatPlayer from '../helpers/FormatPlayer.js' ;
2023-09-01 00:32:11 -04:00
import LogPrefix from '../helpers/LogPrefix.js' ;
2023-05-23 01:14:17 -04:00
import { writeFileSync , readFileSync } from 'node:fs' ;
2023-09-01 00:32:11 -04:00
import { FSPlayer , FSData , FSCareerSavegame } from '../typings/interfaces' ;
2023-05-05 18:41:35 -04:00
2023-08-19 08:50:05 -04:00
export default async ( client :TClient , Channel :string , Message :string , Server :TServer , ServerName :string ) = > {
2023-08-19 20:17:22 -04:00
let isServerOnline = false ;
2023-08-19 08:50:05 -04:00
let playerData :Array < string > = [ ] ;
2023-08-18 20:54:17 -04:00
let noContentImage = 'https://cdn.discordapp.com/attachments/1118960531135541318/1140906691236479036/68efx1.png' ;
2023-08-18 07:18:33 -04:00
const msg = await ( client . channels . resolve ( Channel ) as Discord . TextChannel ) . messages . fetch ( Message ) ;
2023-08-19 08:50:05 -04:00
const serverErrorEmbed = new client . embed ( ) . setColor ( client . config . embedColorRed ) . setTitle ( 'Host did not respond back in time' ) ;
const genericEmbed = new client . embed ( ) ;
2023-08-18 20:54:17 -04:00
2023-08-18 07:18:33 -04:00
const HITALL = async ( ) = > {
2023-09-03 00:15:02 -04:00
let sessionInit = { signal : AbortSignal.timeout ( 8200 ) , headers : { 'User-Agent' : 'Daggerbot - HITALL/undici' } } ;
2023-08-18 07:18:33 -04:00
try {
2023-08-18 20:54:17 -04:00
const hitDSS = await fetch ( Server . ip + '/feed/dedicated-server-stats.json?code=' + Server . code , sessionInit ) . then ( r = > r . json ( ) as Promise < FSData > ) ;
2023-08-19 08:50:05 -04:00
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 ) ;
2023-08-18 20:54:17 -04:00
if ( ! hitDSS ? ? ! hitCSG ) {
2023-09-03 00:15:02 -04:00
if ( hitDSS && ! hitDSS . slots ) return console . log ( ` ${ LogPrefix ( 'MPLoop' ) } DSS failed with unknown slots table for ${ client . MPServerCache [ ServerName ] . name } ` ) ;
if ( hitDSS && ! hitCSG . slotSystem ) return msg . edit ( { content : 'No savegame found or autosave has ran.' , embeds : [ genericEmbed . setColor ( client . config . embedColorOrange ) . setImage ( noContentImage ) ] } ) ;
2023-08-19 08:50:05 -04:00
else return msg . edit ( { embeds : [ serverErrorEmbed ] } ) ;
2023-08-18 20:54:17 -04:00
}
2023-09-03 00:15:02 -04:00
// 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 . includes ( filter ) ) client . MPServerCache [ ServerName ] . name = [ 'Daggerwin' , 'DagMF' ] [ [ 'Official Daggerwin Game Server' , 'Daggerwin Multifarm' ] . indexOf ( filter ) ] ;
}
2023-08-19 20:17:22 -04:00
2023-08-19 08:50:05 -04:00
//Timescale formatting
function formatTimescale ( number : number , digits :number , icon :string ) {
var n = Number ( number ) ;
return n . toLocaleString ( undefined , { minimumFractionDigits : digits } ) + icon
2023-08-15 06:47:31 -04:00
}
2023-08-19 08:50:05 -04:00
// Join/Leave log
function playerLogEmbed ( player :FSPlayer , joinLog :boolean ) {
2023-08-30 04:34:59 -04:00
const logEmbed = new client . embed ( ) . setDescription ( ` ** ${ player . name } ${ FormatPlayer . decoratePlayerIcons ( player ) } ** ${ joinLog ? 'joined' : 'left' } ** ${ client . MPServerCache [ ServerName ] . name } ** at <t: ${ Math . round ( Date . now ( ) / 1000 ) } :t> ` ) ;
2023-08-19 08:50:05 -04:00
if ( joinLog ) return logEmbed . setColor ( client . config . embedColorGreen ) ;
2023-08-30 04:34:59 -04:00
else if ( player . uptime > 0 ) return logEmbed . setColor ( client . config . embedColorRed ) . setFooter ( { text : ` Farmed for ${ FormatPlayer . uptimeFormat ( player . uptime ) } ` } ) ;
2023-08-19 08:50:05 -04:00
else return logEmbed . setColor ( client . config . embedColorRed ) ;
}
2023-05-07 04:41:20 -04:00
2023-08-19 08:50:05 -04:00
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 ;
2023-08-30 04:34:59 -04:00
if ( ! playersOnServer ? ? playersOnServer === undefined ) return console . log ( '[MPLoop] Empty array, 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 ) } ` ) ) ;
2023-08-24 12:06:39 -04:00
2023-08-19 20:17:22 -04:00
// 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 ) ) ;
2023-08-24 12:06:39 -04:00
if ( client . MPServerCache [ ServerName ] . name === null ) return ;
2023-08-19 20:17:22 -04:00
const Database :Array < number > = 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 ;
2023-08-19 08:50:05 -04:00
2023-08-19 20:17:22 -04:00
if ( hitDSS . server . name . length < 1 ) {
2023-08-19 08:50:05 -04:00
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.' ) ] } ) ;
2023-08-19 20:17:22 -04:00
client . MPServerCache [ ServerName ] . status = 'offline'
2023-08-19 08:50:05 -04:00
} else {
2023-08-19 20:17:22 -04:00
isServerOnline = true ;
client . MPServerCache [ ServerName ] . status = 'online' ;
2023-08-19 08:50:05 -04:00
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 } ` } ) ;
2023-08-28 00:23:49 -04:00
msg . edit ( { content : 'This embed updates every 35 seconds.' , embeds : [ serverDetails , playersEmbed ] } ) ;
2023-08-19 08:50:05 -04:00
}
} catch ( err ) {
2023-09-03 00:15:02 -04:00
if ( err . message === 'The operation was aborted due to timeout' ) return msg . edit ( { content : 'Connection timed out.' , embeds : [ serverErrorEmbed ] } ) ;
msg . edit ( { content : null , embeds : [ serverErrorEmbed ] } ) ;
console . log ( client . logTime ( ) , ` Failed to make a request for ${ ServerName } : ` , err . message )
2023-08-19 08:50:05 -04:00
}
2023-05-05 18:41:35 -04:00
}
2023-08-19 08:50:05 -04:00
HITALL ( ) ;
2023-05-05 18:41:35 -04:00
}