$chatId, 'text' => $text, 'parse_mode' => 'HTML', ]; $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $postData, CURLOPT_TIMEOUT => 10, CURLOPT_SSL_VERIFYPEER => false, ]); curl_exec($ch); curl_close($ch); } // 1. بررسی وضعیت دایمند کاربران و کسر ۲ دایمند در هر ساعت $activeUsers = []; if (file_exists(DB_FILE)) { try { $db = new PDO('sqlite:' . DB_FILE); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // ستون last_billed اگر نبود اضافه بشه try { $db->exec("ALTER TABLE users ADD COLUMN last_billed INTEGER DEFAULT 0"); } catch (\Throwable $e) {} $adminId = DEFAULT_ADMIN_ID; try { $stmtAdm = $db->query("SELECT value FROM settings WHERE key = 'admin_id'"); $rowAdm = $stmtAdm->fetch(PDO::FETCH_ASSOC); if ($rowAdm && !empty($rowAdm['value'])) { $adminId = (int) $rowAdm['value']; } } catch (\Throwable $e) {} $now = time(); $stmt = $db->query("SELECT * FROM users WHERE is_active = 1"); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($rows as $u) { $uid = (int) $u['user_id']; if (!in_array($uid, $activeUsers, true)) { $activeUsers[] = $uid; } // کسر ساعتی ۲ دایمند (به جز ادمین) if ($uid !== DEFAULT_ADMIN_ID && $uid !== $adminId) { $lastBilled = (int) ($u['last_billed'] ?? 0); if ($lastBilled === 0) { $lastBilled = (int) ($u['active_since'] ?? $now); $upStmt = $db->prepare("UPDATE users SET last_billed = ? WHERE user_id = ?"); $upStmt->execute([$lastBilled, $uid]); } // اگر بیش از ۳۶۰۰ ثانیه از آخرین کسر گذشته if (($now - $lastBilled) >= 3600) { $curDiamonds = (int) $u['diamonds']; if ($curDiamonds >= 2) { $newDiamonds = $curDiamonds - 2; $upStmt = $db->prepare("UPDATE users SET diamonds = ?, last_billed = ? WHERE user_id = ?"); $upStmt->execute([$newDiamonds, $now, $uid]); } else { // اتمام موجودی -> خاموش کردن سلف $upStmt = $db->prepare("UPDATE users SET is_active = 0 WHERE user_id = ?"); $upStmt->execute([$uid]); // Kill user process $sessDir = "/home/in8wswn/selfbot_php/session/user_{$uid}"; $lockFile = $sessDir . '/runner.lock'; if (file_exists($lockFile)) { $pid = (int) @file_get_contents($lockFile); if ($pid > 0 && function_exists('posix_kill')) { posix_kill($pid, 9); } @unlink($lockFile); } botMsg($uid, "⚠️ موجودی دایمند شما به پایان رسید!\n\nسلف‌بات شما به دلیل اتمام موجودی موقتاً خاموش شد.\nبرای فعال‌سازی دوباره، از دکمه «💎 خرید دایمند» حساب خود را شارژ کنید."); // حذف از لیست اجرای زنده $activeUsers = array_diff($activeUsers, [$uid]); } } } } } catch (\Throwable $e) { echo "[" . date('Y-m-d H:i:s') . "] DB error in supervisor: " . $e->getMessage() . "\n"; } } // 2. چک کردن و بالا آوردن سلف تمام کاربران فعال foreach ($activeUsers as $uid) { $sessDir = __DIR__ . "/session/user_{$uid}"; // الف) اگر کاربر در محدودیت زمانی Flood Wait تلگرام است، اجرا نشود $floodFile = $sessDir . '/flood_wait.txt'; if (file_exists($floodFile)) { $until = (int) @file_get_contents($floodFile); if (time() < $until) { continue; // هنوز زمان فلود ویت تمام نشده } else { @unlink($floodFile); } } // ب) بررسی فایل نشست معتبر $safeFile = $sessDir . '/selfbot.madeline/safe.php'; if (!file_exists($safeFile) || filesize($safeFile) < 5000) { if (isset($db)) { $upStmt = $db->prepare("UPDATE users SET is_active = 0 WHERE user_id = ?"); $upStmt->execute([$uid]); } continue; } $lockFile = $sessDir . '/runner.lock'; $isRunning = false; if (file_exists($lockFile)) { $fpTest = @fopen($lockFile, 'c+'); if ($fpTest) { if (!@flock($fpTest, LOCK_EX | LOCK_NB)) { $isRunning = true; } else { @flock($fpTest, LOCK_UN); } @fclose($fpTest); } } if (!$isRunning) { // پروسس رانر فعال نیست؛ قبل از اجرا مطمئن شو ورکر معلقی از قبل نمانده @unlink($lockFile); if (function_exists('posix_kill')) { foreach (glob('/proc/[0-9]*') as $p) { $pid = (int) basename($p); $cmd = @file_get_contents($p . '/cmdline'); if ($cmd && strpos($cmd, "user_{$uid}") !== false && strpos($cmd, 'cron_runner.php') === false) { @posix_kill($pid, 9); } } } foreach (glob($sessDir . '/selfbot.madeline/*.lock') as $lk) { @unlink($lk); } echo "[" . date('Y-m-d H:i:s') . "] Starting runner for active user {$uid}...\n"; $cmd = "/opt/cpanel/ea-php83/root/usr/bin/php -q /home/in8wswn/selfbot_php/run_user.php {$uid} >> /home/in8wswn/selfbot_php/cron.log 2>&1 &"; $desc = [ 0 => ['pipe', 'r'], 1 => ['file', '/dev/null', 'w'], 2 => ['file', '/dev/null', 'w'] ]; $proc = proc_open($cmd, $desc, $pipes); if (is_resource($proc)) { proc_close($proc); } } } // 3. Check and keep alive StAbad Telegram Bot $stabadPidFile = '/home/in8wswn/stabad_bot/bot.pid'; $stabadDisabledFile = '/home/in8wswn/stabad_bot/disabled.lock'; $botRunning = false; if (file_exists($stabadDisabledFile)) { $botRunning = true; // Manually disabled by owner } elseif (file_exists($stabadPidFile)) { $bpid = (int) @file_get_contents($stabadPidFile); if ($bpid > 0 && @file_exists("/proc/{$bpid}")) { $botRunning = true; } } if (!$botRunning) { echo "[" . date('Y-m-d H:i:s') . "] Auto-starting StAbad Telegram Bot supervisor...\n"; $cmd = "cd /home/in8wswn/stabad_bot && /home/in8wswn/stabad_bot_venv/bin/python3 /home/in8wswn/stabad_bot/runner.py >> /home/in8wswn/stabad_bot/bot.log 2>&1 &"; $desc = [ 0 => ['pipe', 'r'], 1 => ['file', '/dev/null', 'w'], 2 => ['file', '/dev/null', 'w'] ]; $proc = proc_open($cmd, $desc, $pipes); if (is_resource($proc)) { proc_close($proc); } } echo "[" . date('Y-m-d H:i:s') . "] Master Supervisor check completed for " . count($activeUsers) . " user(s).\n";