| 'use strict'; |
| try { require('dotenv').config(); } catch (_) {} |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| const ATERNOS_USER = process.env.ATERNOS_USER || ''; |
| const ATERNOS_PASS = process.env.ATERNOS_PASS || ''; |
| const ATERNOS_SERVER = process.env.ATERNOS_SERVER || ''; |
| const TOTAL_TIMEOUT = 9 * 60000; |
| const ONLINE_TIMEOUT = 6 * 60000; |
|
|
| const sleep = ms => new Promise(r => setTimeout(r, Math.max(0, ms))); |
| const randInt = (a, b) => Math.floor(Math.random() * (b - a + 1)) + a; |
|
|
| function log(emoji, msg) { |
| const ts = new Date().toISOString().replace('T', ' ').slice(0, 19); |
| console.log(`[${ts}] [ATERNOS] ${emoji} ${msg}`); |
| } |
|
|
| async function humanType(page, selector, text) { |
| await page.focus(selector); |
| for (const ch of text) { |
| await page.keyboard.type(ch, { delay: randInt(60, 180) }); |
| if (Math.random() < 0.08) await sleep(randInt(100, 400)); |
| } |
| } |
|
|
| async function loadPuppeteer() { |
| try { |
| const p = require('puppeteer'); |
| log('📦', 'puppeteer محلي'); |
| return { puppeteer: p }; |
| } catch (_) {} |
| try { |
| const p = require('puppeteer-core'); |
| const ch = require('@sparticuz/chromium'); |
| log('📦', 'puppeteer-core + @sparticuz/chromium'); |
| return { |
| puppeteer: p, |
| executablePath: await ch.executablePath(), |
| args: ch.args, |
| defaultViewport: ch.defaultViewport, |
| }; |
| } catch (_) {} |
| return null; |
| } |
|
|
| async function getServerStatus(page) { |
| try { |
| return await page.evaluate(() => { |
| const sels = [ |
| '.server-status','.status','[class*="status"]', |
| '#server-status','.statuslabel','.label', |
| ]; |
| for (const sel of sels) { |
| const el = document.querySelector(sel); |
| if (el) { |
| const t = el.textContent?.trim().toLowerCase() || ''; |
| if (t.includes('online')) return 'online'; |
| if (t.includes('offline')) return 'offline'; |
| if (t.includes('starting') || t.includes('loading')) return 'starting'; |
| if (t.includes('stopping')) return 'stopping'; |
| } |
| } |
| const btn = document.querySelector('.btn-success, [class*="start"]'); |
| if (btn) return 'offline'; |
| return 'unknown'; |
| }); |
| } catch (_) { return 'unknown'; } |
| } |
|
|
| async function clickStart(page) { |
| try { |
| const btns = [ |
| '.btn-success','.start-btn','[class*="start"]', |
| 'button[class*="start"]','#start', |
| ]; |
| for (const sel of btns) { |
| const btn = await page.$(sel); |
| if (btn) { await btn.click(); return true; } |
| } |
| return false; |
| } catch (_) { return false; } |
| } |
|
|
| async function main() { |
| if (!ATERNOS_USER || !ATERNOS_PASS) { |
| log('⚠️', 'ATERNOS_USER / ATERNOS_PASS غير مضبوطان — تخطي'); |
| log('💡', 'أضف ATERNOS_USER و ATERNOS_PASS في Settings → Variables'); |
| process.exit(1); |
| } |
|
|
| const lib = await loadPuppeteer(); |
| if (!lib) { |
| log('❌', 'puppeteer غير متاح في هذه البيئة'); |
| log('💡', 'في HuggingFace: شغّل السيرفر يدوياً من لوحة Aternos'); |
| process.exit(1); |
| } |
|
|
| const { puppeteer, executablePath, args, defaultViewport } = lib; |
| log('🌐', `تسجيل دخول | مستخدم: ${ATERNOS_USER}`); |
|
|
| let browser = null; |
| const timer = setTimeout(() => { |
| log('⏱️', 'انتهت المهلة الإجمالية (9 دقائق)'); |
| try { browser?.close(); } catch (_) {} |
| process.exit(2); |
| }, TOTAL_TIMEOUT); |
|
|
| try { |
| browser = await puppeteer.launch({ |
| headless: 'new', |
| args: args || [ |
| '--no-sandbox','--disable-setuid-sandbox','--disable-dev-shm-usage', |
| '--disable-gpu','--no-first-run','--no-zygote','--single-process', |
| '--disable-extensions','--disable-background-networking', |
| ], |
| defaultViewport: defaultViewport || { width: 1280, height: 720 }, |
| ...(executablePath ? { executablePath } : {}), |
| }); |
|
|
| const page = await browser.newPage(); |
| await page.setUserAgent( |
| 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36' |
| ); |
| await page.setExtraHTTPHeaders({ 'Accept-Language': 'en-US,en;q=0.9' }); |
|
|
| log('🔗', 'الانتقال إلى aternos.org...'); |
| await page.goto('https://aternos.org/go/', { waitUntil: 'networkidle2', timeout: 30000 }); |
|
|
| log('🔑', 'ملء بيانات الدخول...'); |
| await page.waitForSelector('#user', { timeout: 15000 }); |
| await humanType(page, '#user', ATERNOS_USER); |
| await sleep(randInt(400, 900)); |
| await humanType(page, '#password', ATERNOS_PASS); |
| await sleep(randInt(300, 700)); |
| await page.click('.login-button, [data-id="login"], button[type="submit"]'); |
| log('⏳', 'انتظار تسجيل الدخول...'); |
| await page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 20000 }).catch(() => {}); |
| await sleep(randInt(1500, 3000)); |
|
|
| log('🔗', 'صفحة السيرفرات...'); |
| await page.goto('https://aternos.org/servers/', { waitUntil: 'networkidle2', timeout: 20000 }) |
| .catch(() => page.goto('https://aternos.org/panel/', { waitUntil: 'networkidle2', timeout: 20000 }).catch(() => {})); |
| await sleep(randInt(1000, 2500)); |
|
|
| if (ATERNOS_SERVER) { |
| log('🖱️', `البحث عن: ${ATERNOS_SERVER}`); |
| try { |
| const links = await page.$$('.server-name,.server .name,[class*="server"]'); |
| for (const link of links) { |
| const text = await page.evaluate(el => el.textContent?.trim(), link); |
| if (text?.toLowerCase().includes(ATERNOS_SERVER.toLowerCase())) { |
| await link.click(); |
| log('✅', `اختيار: ${text}`); |
| await sleep(randInt(1500, 3000)); |
| break; |
| } |
| } |
| } catch (_) {} |
| } else { |
| try { |
| const first = await page.$('.server,.server-card,[class*="server-item"]'); |
| if (first) { await first.click(); await sleep(randInt(1500, 3000)); } |
| } catch (_) {} |
| } |
|
|
| const url = page.url(); |
| if (!url.includes('/server/')) { |
| await page.goto('https://aternos.org/server/', { waitUntil: 'networkidle2', timeout: 20000 }).catch(() => {}); |
| await sleep(randInt(1000, 2000)); |
| } |
|
|
| log('🔍', 'فحص حالة السيرفر...'); |
| let status = await getServerStatus(page); |
| log('📊', `الحالة: ${status}`); |
|
|
| if (status === 'online') { |
| log('✅', 'السيرفر يعمل بالفعل!'); |
| clearTimeout(timer); |
| await browser.close(); |
| process.exit(0); |
| } |
|
|
| if (status === 'offline' || status === 'unknown') { |
| const clicked = await clickStart(page); |
| log(clicked ? '✅' : '⚠️', clicked ? 'تم النقر على Start' : 'لم يُعثر على زر Start'); |
| } |
|
|
| log('⏳', `انتظار Online (مهلة: ${Math.round(ONLINE_TIMEOUT / 60000)} دقائق)...`); |
| const start = Date.now(); |
| let last = ''; |
| while (Date.now() - start < ONLINE_TIMEOUT) { |
| await sleep(15000); |
| await page.reload({ waitUntil: 'networkidle2', timeout: 15000 }).catch(() => {}); |
| await sleep(2000); |
| status = await getServerStatus(page); |
| if (status !== last) { log('📊', `الحالة: ${status}`); last = status; } |
| if (status === 'online') { |
| log('🎉', '✅ السيرفر Online! البوتات ستتصل قريباً'); |
| clearTimeout(timer); |
| await browser.close(); |
| process.exit(0); |
| } |
| if (status === 'offline') { |
| log('🔄', 'لا يزال Offline — محاولة Start مرة أخرى...'); |
| await clickStart(page); |
| } |
| } |
|
|
| log('⏱️', 'انتهت مهلة الانتظار — السيرفر لم يبدأ'); |
| clearTimeout(timer); |
| await browser.close(); |
| process.exit(2); |
|
|
| } catch (err) { |
| log('❌', `خطأ: ${err.message}`); |
| clearTimeout(timer); |
| try { browser?.close(); } catch (_) {} |
| process.exit(1); |
| } |
| } |
|
|
| main(); |
|
|