@rifaichump/aternos
Version:
An unofficial API client to manage and interact with Aternos servers using Puppeteer.
453 lines (447 loc) • 18.3 kB
JavaScript
;
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