import fs from 'fs' import { exec } from 'child_process' import { skinDB } from '../database/init.js' import initLog from '../utils/log.js' import { download } from '../download/dowload.js' const log = initLog("DDNSS") /** * This function takes a Teeworlds coutry code and * maps it to a two letter country code instead * * @param number Teeworlds country code * * @returns Two letter country code */ export function mapCountryCode(code) { const codes = fs.readFileSync('./libs/ddnss/countrycodes.json') const json = JSON.parse(codes) for (const country in json) { if(country == code) return json[country] } /* If none is found, just return default */ return "default" } export async function ddnssStart() { const getServers = await download('https://ddnet.tw/status/index.json', "_RETURN_VALUE_") const servers = await JSON.parse(getServers) log(`Found ${servers.length} online servers!`) for (const server of servers) { const connection = `${server.ip}:${server.port}` if (!(server.num_clients > 0 && server.num_clients < (server.max_clients - 2))) { log(`Server (essentially) full! >> ${connection} -> ${server.num_clients}/${server.max_clients} clients`) continue } if(server.password) { log(`Server is locked >> ${connection}`) continue } log(`Connecting to server >> ${connection}`) await scrapeServer(`${connection}`) } } function scrapeServer(server) { // TODO: Maybe fix the paths to be dynamic? Or have some sort of buildscript... // -- BurnyLlama const command = `./ddnss/build/DDNet "ui_server_address ${server}" -f ddnss/build/config.conf` return new Promise((resolve, reject) => { exec(command, { encoding: 'utf8' }, (err, stdout, stderr) => { try { const skinData = JSON.parse(stdout) if (skinData === null) return resolve() const stmt = skinDB.prepare (` INSERT INTO "skindata" VALUES ( $timestamp, $player, $clan, $flag, $twFlag, $skin, $useColor, $colorBodyRaw, $colorBodyHex, $colorFeetRaw, $colorFeetHex ) `) const currentTime = Date.now() for (const entry of skinData) { stmt.run({ timestamp: currentTime, player: entry.player, clan: entry.clan, flag: mapCountryCode(entry.flag), twFlag: entry.flag, skin: entry.skindata.skin, useColor: entry.skindata.useColor, colorBodyRaw: entry.skindata.colorBody.raw, colorBodyHex: entry.skindata.colorBody.hex, colorFeetRaw: entry.skindata.colorFeet.raw, colorFeetHex: entry.skindata.colorFeet.hex }) } } catch (e) { log(`Failed to handle ${server}!`) } resolve() }) }) }