'use strict'; const axios = require("axios"); const fs = require("fs-extra"); const { XMLParser } = require("fast-xml-parser"); const pLimit = require("p-limit"); const parser = new XMLParser({ ignoreAttributes: false, attributeNamePrefix: "" }); const limit = pLimit(5); const serverLimit = pLimit(20); const LOBBY = "https://lobby.ogame.gameforge.com/api/servers"; const XMLS = [ "players", "alliances", "universe", "serverData" ]; const HIGHSCORE_TYPES = { 0: "0", 1: "1", 2: "2", 3: "3", 4: "4", 5: "5", 6: "6", 7: "7", 8: "8", 9: "9", 10: "10", 11: "11" }; const HIGHSCORE_CATEGORIES = { 1: "1", 2: "2" }; async function loadXml(url) { await sleep(500); const maxTry = 10; for (let attempt = 1; attempt <= maxTry; attempt++) { try { const res = await axios.get(url, { timeout: 60000 }); return parser.parse(res.data); } catch (error) { console.log( `Hiba (${attempt}/${maxTry}): ${url} - ${error.response?.status || error.message}` ); if (attempt < maxTry) { await sleep(5000); } } } console.log(`Sikertelen: ${url}`); return null; } async function processServer(server) { const lang = server.language; const number = server.number; const serverName = `s${number}-${lang}`; console.log(serverName); const base = `https://${serverName}.ogame.gameforge.com/api`; const result = { lobby: server, api: {} }; await Promise.all( XMLS.map(xml => limit(async () => { result.api[xml] = await loadXml(`${base}/${xml}.xml`); }) ) ); await fs.ensureDir(`data/${lang}`); await fs.writeJson( `data/${lang}/${serverName}.json`, result, { spaces: 2 } ); } async function processHighscore(server) { const serverName = `s${server.number}-${server.language}`; const base = `https://${serverName}.ogame.gameforge.com/api`; const result = { server: serverName, generated: new Date().toISOString(), player: {}, alliance: {} }; for (const [catName, catId] of Object.entries(HIGHSCORE_CATEGORIES)) { result[catName] = {}; for (const [typeName, typeId] of Object.entries(HIGHSCORE_TYPES)) { console.log( `${serverName} ${catName} ${typeName}` ); const url = `${base}/highscore.xml?category=${catId}&type=${typeId}`; result[catName][typeName] = await loadXml(url); } } await fs.ensureDir(`data/${server.language}`); await fs.writeJson( `data/${server.language}/${serverName}-highscore.json`, result, { spaces: 2 } ); } async function main() { const { data: servers } = await axios.get(LOBBY); if (MODE_SERVER) { await Promise.all( servers.map(server => serverLimit(() => processServer(server)) ) ); } if (MODE_HIGHSCORE) { await Promise.all( servers.map(server => serverLimit(() => processHighscore(server)) ) ); } console.log("Kész."); } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } const args = process.argv.slice(2); const MODE_SERVER = args.includes("-server"); const MODE_HIGHSCORE = args.includes("-highscore"); if (!MODE_SERVER && !MODE_HIGHSCORE) { console.log(` Usage: OgameStats -server OgameStats -highscore Press any key to exit... `); process.stdin.setRawMode(true); process.stdin.resume(); process.stdin.once("data", () => { process.exit(0); }); } else { main(); }