UNPKG

@rifaichump/aternos

Version:

An unofficial API client to manage and interact with Aternos servers using Puppeteer.

453 lines (447 loc) 18.3 kB
"use strict"; const __create = Object.create; const __defProp = Object.defineProperty; const __getOwnPropDesc = Object.getOwnPropertyDescriptor; const __getOwnPropNames = Object.getOwnPropertyNames; const __getProtoOf = Object.getPrototypeOf; const __hasOwnProp = Object.prototype.hasOwnProperty; const __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; const __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; const __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); const __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts const index_exports = {}; __export(index_exports, { getServerList: () => getServerList, loginToAternos: () => loginToAternos, manageServer: () => manageServer, viewConsoleLive: () => viewConsoleLive }); module.exports = __toCommonJS(index_exports); // src/global/set.ts const import_path = __toESM(require("path")); const import_fs = __toESM(require("fs")); const import_child_process = require("child_process"); const import_freeport = __toESM(require("freeport")); function resolveChromiumPath() { const localPath = import_path.default.resolve( __dirname, "../../stable-chromium/chrome-linux/chrome-linux64/chrome" ); if (import_fs.default.existsSync(localPath)) return localPath; try { return (0, import_child_process.execSync)("which chromium").toString().trim(); } catch { console.error("Chromium not found. Install with apt."); process.exit(1); } } function getFreePort() { return new Promise((resolve, reject) => { (0, import_freeport.default)((err, port) => { if (err || port === null) return reject(err); resolve(port); }); }); } function randomUserAgent() { const data = { platforms: ["Windows NT 10.0; Win64; x64", "Macintosh; Intel Mac OS X 10_15_7"], browsers: { chrome: ["125.0.0.0", "124.0.0.0"], firefox: ["126.0", "125.0"], edge: ["125.0.2535.51"] } }; const randomItem = (arr) => arr[Math.floor(Math.random() * arr.length)]; const os = randomItem(data.platforms); const browserKeys = Object.keys(data.browsers); const browserName = randomItem(browserKeys); const browserVersion = randomItem(data.browsers[browserName]); if (browserName === "firefox") { return `Mozilla/5.0 (${os}; rv:${browserVersion}) Gecko/20100101 Firefox/${browserVersion}`; } if (browserName === "edge") { const chromeVersion = randomItem(data.browsers.chrome); return `Mozilla/5.0 (${os}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${chromeVersion} Safari/537.36 Edg/${browserVersion}`; } return `Mozilla/5.0 (${os}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${browserVersion} Safari/537.36`; } // src/login.ts const import_puppeteer_core = __toESM(require("puppeteer-core")); const import_puppeteer_extra = __toESM(require("puppeteer-extra")) const import_puppeteer_plugin = __toESM(require("puppeteer-extra-plugin-stealth")) const import_proxy_chain = require("proxy-chain"); const import_fs2 = __toESM(require("fs")); const import_path2 = __toESM(require("path")); const cookiesPath = import_path2.default.resolve(process.cwd(), "aternos-cookies.json"); async function loginToAternos(user, pass) { const puppeteer = import_puppeteer_extra.default.use(import_puppeteer_plugin.default()) if (import_fs2.default.existsSync(cookiesPath)) { try { const raw = import_fs2.default.readFileSync(cookiesPath, "utf8"); if (raw.trim().length > 0) { const cookies2 = JSON.parse(raw); return cookies2; } } catch { console.warn("\u26A0\uFE0F Invalid or corrupted cookies file. Regenerating..."); } } const port = await getFreePort(); const proxyServer = new import_proxy_chain.Server({ port }); await proxyServer.listen(() => { console.log(`\u{1F9EA} Proxy listening on 127.0.0.1:${port}`); }); const browser = await puppeteer.launch({ headless: true, executablePath: resolveChromiumPath(), args: [ "--ignore-certificate-errors", "--disable-gpu", "--disable-software-rasterizer", "--disable-dev-shm-usage", "--no-sandbox", `--proxy-server=127.0.0.1:${port}` ] }); const page = await browser.newPage(); await page.setUserAgent( randomUserAgent() ); await page.goto("https://aternos.org/go/", { waitUntil: "domcontentloaded", timeout: 6e4 }); await page.type("input.username", user, { delay: 50 }); await page.type("input.password", pass, { delay: 50 }); await page.click("button.login-button"); await new Promise((resolve) => setTimeout(resolve, 5e3)); const cookies = await page.cookies(); import_fs2.default.writeFileSync(cookiesPath, JSON.stringify(cookies, null, 2)); await browser.close(); await proxyServer.close(true); return cookies; } // src/server.ts const import_puppeteer_core2 = __toESM(require("puppeteer-core")); const import_proxy_chain2 = require("proxy-chain"); async function getServerList(cookies) { const port = await getFreePort(); const proxyServer = new import_proxy_chain2.Server({ port }); await proxyServer.listen(() => { }); const browser = await import_puppeteer_core2.default.launch({ headless: true, executablePath: resolveChromiumPath(), args: [ "--ignore-certificate-errors", "--disable-gpu", "--disable-software-rasterizer", "--disable-dev-shm-usage", "--no-sandbox", `--proxy-server=127.0.0.1:${port}` ] }); const page = await browser.newPage(); let servers = []; try { await page.setUserAgent( randomUserAgent() ); await page.setCookie(...cookies); await page.goto("https://aternos.org/servers/", { waitUntil: "domcontentloaded", timeout: 6e4 }); if (page.url().includes("/go/")) { throw new Error("Authentication failed. Redirected back to login page."); } await page.waitForSelector(".servercard", { timeout: 2e4 }); servers = await page.evaluate(() => { const serverList = []; const serverCards = document.querySelectorAll(".servercard"); serverCards.forEach((card) => { const serverName = card.querySelector(".server-name")?.textContent?.trim() || null; const serverId = card.querySelector(".server-id")?.textContent?.trim().replace("#", "") || null; const status = card.classList.contains("offline") ? "offline" : card.classList.contains("online") ? "online" : "unknown"; const software = card.querySelector(".server-software-name")?.textContent?.trim() || null; const players = card.querySelector(".statusplayerbadge")?.textContent?.trim() || null; serverList.push({ name: serverName, id: serverId, status, software, players }); }); return serverList; }); } catch (error) { console.error(`\u274C An error occurred during server list fetching:`, error); } finally { await browser.close(); await proxyServer.close(true); } return { servers }; } // src/servermanager.ts const import_puppeteer_core3 = __toESM(require("puppeteer-core")); const import_proxy_chain3 = require("proxy-chain"); async function manageServer(cookies, serverId, task) { if (!serverId) { return task === "info" ? null : { success: false, message: "Error: Server ID is required." }; } const maxAttempts = 3; for (let attempt = 1; attempt <= maxAttempts; attempt++) { let browser = null; let proxyServer = null; try { const port = await getFreePort(); proxyServer = new import_proxy_chain3.Server({ port }); await proxyServer.listen(() => { }); browser = await import_puppeteer_core3.default.launch({ headless: true, executablePath: resolveChromiumPath(), args: [ "--ignore-certificate-errors", "--disable-gpu", "--disable-software-rasterizer", "--disable-dev-shm-usage", "--no-sandbox", `--proxy-server=127.0.0.1:${port}` ] }); const page = await browser.newPage(); await page.setUserAgent( randomUserAgent() ); await page.setCookie(...cookies); await page.goto("https://aternos.org/servers/", { waitUntil: "domcontentloaded", timeout: 6e4 }); const serverCardFound = await page.evaluate((id) => { const serverCards = document.querySelectorAll(".servercard"); for (const card of serverCards) { const idElement = card.querySelector(".server-id"); if (idElement && idElement.textContent?.trim().replace("#", "") === id) { card.click(); return true; } } return false; }, serverId); if (!serverCardFound) { throw new Error(`Server with ID '${serverId}' not found on the page.`); } await new Promise((resolve) => setTimeout(resolve, 3e3)); if (task === "info") { const info = await page.evaluate(() => { const getText = (selector) => document.querySelector(selector)?.textContent?.trim() || null; return { shareUrl: getText("#share-url"), address: getText("#ip"), port: getText("#port"), software: getText("#software"), version: getText("#version"), players: getText(".js-players"), ram: getText(".js-ram") }; }); return info; } else { const currentStatus = await page.evaluate(() => document.querySelector(".statuslabel-label")?.textContent?.trim() || null); if (task === "start") { if (currentStatus === "Online") { const timeRemaining = await page.evaluate(() => document.querySelector(".server-end-countdown")?.textContent?.trim() || "N/A"); return { success: true, message: "Server is already online.", status: "Online", timeRemaining }; } if (currentStatus !== "Offline") { return { success: false, message: `Server is not offline. Current status: ${currentStatus}` }; } } if ((task === "stop" || task === "restart") && currentStatus !== "Online") { return { success: false, message: `Server is not online. Current status: ${currentStatus}` }; } const selector = `#${task}`; await page.waitForSelector(selector, { visible: true, timeout: 1e4 }); await page.click(selector); if (task === "start") { const keywords = ["yes", "okay", "accept", "confirm", "agree", "continue", "proceed", "next", "ok"]; const clickDialogButton = async () => { try { await page.waitForFunction((kws) => { const buttons = document.querySelectorAll(".alert-buttons button.btn-success"); for (const button of buttons) { const buttonText = button.textContent?.trim().toLowerCase() || ""; if (kws.some((kw) => buttonText.includes(kw))) { button.click(); return true; } } return false; }, { timeout: 5e3 }, keywords); } catch (e) { } }; await clickDialogButton(); await clickDialogButton(); try { await page.waitForSelector("#confirm", { visible: true, timeout: 15e3 }); await page.click("#confirm"); } catch (e) { } } if (task === "start" || task === "restart") { await page.waitForFunction(() => document.querySelector(".statuslabel-label")?.textContent?.trim() === "Online", { timeout: 18e4 }); } else if (task === "stop") { await page.waitForFunction(() => document.querySelector(".statuslabel-label")?.textContent?.trim() === "Offline", { timeout: 6e4 }); } return { success: true, message: `Action '${task}' performed successfully.` }; } } catch (error) { const errorMessage = error.message.toLowerCase(); if (browser) await browser.close(); if (proxyServer) await proxyServer.close(true); if ((errorMessage.includes("connection") || errorMessage.includes("target closed")) && attempt < maxAttempts) { console.error(`Attempt ${attempt} failed with connection error. Retrying...`); await new Promise((resolve) => setTimeout(resolve, 2e3)); } else { console.error(`Failed to perform task '${task}' on server ${serverId}.`, error); return task === "info" ? null : { success: false, message: error.message + "Retry Rerun the console i think delay it" }; } } finally { if (browser && !browser.process()?.killed) await browser.close(); if (proxyServer) await proxyServer.close(true); } } return task === "info" ? null : { success: false, message: `Action failed after all ${maxAttempts} attempts.Retry Rerun the console i think delay it` }; } // src/console.ts const import_puppeteer_core4 = __toESM(require("puppeteer-core")); const import_proxy_chain4 = require("proxy-chain"); const import_gradient_string = __toESM(require("gradient-string")); const logGradients = [ (0, import_gradient_string.default)("cyan", "lightgreen"), (0, import_gradient_string.default)("orange", "yellow"), (0, import_gradient_string.default)("#FF7E5F", "#FEB47B") ]; async function viewConsoleLive(cookies, serverId) { if (!serverId) { console.error("Error: Server ID is required."); return; } let browser = null; let proxyServer = null; try { const port = await getFreePort(); proxyServer = new import_proxy_chain4.Server({ port }); await proxyServer.listen(() => { }); browser = await import_puppeteer_core4.default.launch({ headless: true, executablePath: resolveChromiumPath(), args: [ "--ignore-certificate-errors", "--disable-gpu", "--disable-dev-shm-usage", "--no-sandbox", `--proxy-server=127.0.0.1:${port}` ] }); const page = await browser.newPage(); await page.setUserAgent(randomUserAgent()); await page.setCookie(...cookies); await page.goto("https://aternos.org/servers/", { waitUntil: "domcontentloaded", timeout: 6e4 }); const serverCardFound = await page.evaluate((id) => { const serverCards = document.querySelectorAll(".servercard"); for (const card of serverCards) { const idElement = card.querySelector(".server-id"); if (idElement && idElement.textContent?.trim().replace("#", "") === id) { card.click(); return true; } } return false; }, serverId); if (!serverCardFound) { throw new Error(`Server with ID '${serverId}' not found on the page.`); } await new Promise((resolve) => setTimeout(resolve, 3e3)); await page.goto("https://aternos.org/console/", { waitUntil: "domcontentloaded", timeout: 6e4 }); await page.waitForSelector("#console", { timeout: 2e4 }); console.log(import_gradient_string.default.atlas.multiline("--- LIVE CONSOLE ---")); const seenLogs = /* @__PURE__ */ new Set(); while (true) { const allLogs = await page.evaluate( () => Array.from(document.querySelectorAll("#console .line")).map((el) => el.textContent || "") ); const newLogs = allLogs.filter((log) => !seenLogs.has(log)); if (newLogs.length > 0) { for (const log of newLogs) { seenLogs.add(log); const cleanedLog = log.replace(/^\[.*?\]\s*/, ""); const randomGradient = logGradients[Math.floor(Math.random() * logGradients.length)]; if (cleanedLog.trim()) { console.log(randomGradient(cleanedLog)); } const connectMatch = /Player connected: (.*?),\s*xuid:/.exec(log); if (connectMatch && connectMatch[1]) { await new Promise((resolve) => setTimeout(resolve, 1e3)); const playerName = connectMatch[1]; const welcomeMessage = `/say \xA7bWelcome, \xA7e${playerName}\xA7b!`; await page.type("#c-input", welcomeMessage); await page.keyboard.press("Enter"); } const disconnectMatch = /Player disconnected: (.*?),\s*xuid:/.exec(log); if (disconnectMatch && disconnectMatch[1]) { await new Promise((resolve) => setTimeout(resolve, 1e3)); const playerName = disconnectMatch[1]; const goodbyeMessage = `/say \xA7cBye, ${playerName}!`; await page.type("#c-input", goodbyeMessage); await page.keyboard.press("Enter"); } } } await new Promise((resolve) => setTimeout(resolve, 2e3)); } } catch (error) { console.error(import_gradient_string.default.passion("An error occurred in the console viewer:")); if (error instanceof Error) { console.error(import_gradient_string.default.passion(error.message)); } else { console.error(import_gradient_string.default.passion(String(error))); } } finally { if (browser) await browser.close(); if (proxyServer) await proxyServer.close(true); console.log(import_gradient_string.default.atlas.multiline("--- CONSOLE CLOSED ---")); } } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { getServerList, loginToAternos, manageServer, viewConsoleLive }); //# sourceMappingURL=index.js.map