UNPKG

@rifaichump/aternos

Version:

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

417 lines (412 loc) 15.9 kB
// node_modules/tsup/assets/esm_shims.js import path from "path"; import { fileURLToPath } from "url"; const getFilename = () => fileURLToPath(import.meta.url); const getDirname = () => path.dirname(getFilename()); const __dirname = /* @__PURE__ */ getDirname(); // src/global/set.ts import path2 from "path"; import fs from "fs"; import { execSync } from "child_process"; import freeport from "freeport"; function resolveChromiumPath() { const localPath = path2.resolve( __dirname, "../../stable-chromium/chrome-linux/chrome-linux64/chrome" ); if (fs.existsSync(localPath)) return localPath; try { return execSync("which chromium").toString().trim(); } catch { console.error("Chromium not found. Install with apt."); process.exit(1); } } function getFreePort() { return new Promise((resolve, reject) => { freeport((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 import puppeteer from "puppeteer-core"; import { Server as ProxyChainServer } from "proxy-chain"; import fs2 from "fs"; import path3 from "path"; const cookiesPath = path3.resolve(process.cwd(), "aternos-cookies.json"); async function loginToAternos(user, pass) { if (fs2.existsSync(cookiesPath)) { try { const raw = fs2.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 ProxyChainServer({ 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(); fs2.writeFileSync(cookiesPath, JSON.stringify(cookies, null, 2)); await browser.close(); await proxyServer.close(true); return cookies; } // src/server.ts import puppeteer2 from "puppeteer-core"; import { Server as ProxyChainServer2 } from "proxy-chain"; async function getServerList(cookies) { const port = await getFreePort(); const proxyServer = new ProxyChainServer2({ port }); await proxyServer.listen(() => { }); const browser = await puppeteer2.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 import puppeteer3 from "puppeteer-core"; import { Server as ProxyChainServer3 } from "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 ProxyChainServer3({ port }); await proxyServer.listen(() => { }); browser = await puppeteer3.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 import puppeteer4 from "puppeteer-core"; import { Server as ProxyChainServer4 } from "proxy-chain"; import gradient from "gradient-string"; const logGradients = [ gradient("cyan", "lightgreen"), gradient("orange", "yellow"), gradient("#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 ProxyChainServer4({ port }); await proxyServer.listen(() => { }); browser = await puppeteer4.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(gradient.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(gradient.passion("An error occurred in the console viewer:")); if (error instanceof Error) { console.error(gradient.passion(error.message)); } else { console.error(gradient.passion(String(error))); } } finally { if (browser) await browser.close(); if (proxyServer) await proxyServer.close(true); console.log(gradient.atlas.multiline("--- CONSOLE CLOSED ---")); } } export { getServerList, loginToAternos, manageServer, viewConsoleLive }; //# sourceMappingURL=index.mjs.map