prepare("UPDATE users SET is_active = 0 WHERE user_id = ?"); $up->execute([$userId]); } catch (\Throwable $e) {} exit(0); } // 3. پاکسازی ورکرهای زامبی قدیمی و قفل‌های معلق این کاربر if (function_exists('posix_kill')) { $myPid = getmypid(); foreach (glob('/proc/[0-9]*') as $p) { $pid = (int) basename($p); if ($pid === $myPid) continue; $cmd = @file_get_contents($p . '/cmdline'); if ($cmd && strpos($cmd, "user_{$userId}") !== false && strpos($cmd, 'run_user.php') === false) { @posix_kill($pid, 9); } } } foreach (glob($session . '/*.lock') as $lk) { @unlink($lk); } $lockFile = $sessionDir . '/runner.lock'; $lockFp = fopen($lockFile, 'c+'); if (!$lockFp || !flock($lockFp, LOCK_EX | LOCK_NB)) { // پروسس این کاربر در حال حاضر فعال است exit(0); } ftruncate($lockFp, 0); fwrite($lockFp, (string) getmypid()); fflush($lockFp); register_shutdown_function(function() use ($lockFp, $lockFile) { if ($lockFp) { @flock($lockFp, LOCK_UN); @fclose($lockFp); } @unlink($lockFile); }); require_once __DIR__ . '/vendor/autoload.php'; require_once __DIR__ . '/src/Store.php'; require_once __DIR__ . '/src/SelfBotHandler.php'; // مقداردهی اولیه به Store برای همین کاربر Store::setUser($userId); use danog\MadelineProto\Logger; use danog\MadelineProto\Settings; use danog\MadelineProto\Settings\AppInfo; $config = require __DIR__ . '/config.php'; $settings = new Settings; $appInfo = new AppInfo; $appInfo->setApiId((int) $config['api_id']); $appInfo->setApiHash((string) $config['api_hash']); $settings->setAppInfo($appInfo); $settings->getLogger() ->setType(Logger::FILE_LOGGER) ->setExtra($logFile) ->setLevel(Logger::LEVEL_WARNING) ->setMaxSize(3 * 1024 * 1024); echo "[" . date('Y-m-d H:i:s') . "] Starting SelfBot loop for user {$userId}...\n"; try { SelfBotHandler::startAndLoop($session, $settings); } catch (\Throwable $e) { $msg = $e->getMessage(); echo "[" . date('Y-m-d H:i:s') . "] SelfBot loop for user {$userId} ended: " . $msg . "\n"; if (preg_match('/FLOOD_WAIT_(\d+)/', $msg, $m)) { $waitSeconds = (int) $m[1]; file_put_contents($floodFile, (string)(time() + $waitSeconds + 60)); echo "[" . date('Y-m-d H:i:s') . "] Set FLOOD_WAIT until " . date('Y-m-d H:i:s', time() + $waitSeconds + 60) . " for user {$userId}\n"; } elseif (stripos($msg, 'AUTH_KEY_UNREGISTERED') !== false || stripos($msg, 'SESSION_REVOKED') !== false || stripos($msg, 'SESSION_EXPIRED') !== false || stripos($msg, 'USER_DEACTIVATED') !== false) { echo "[" . date('Y-m-d H:i:s') . "] Session revoked for user {$userId}. Deactivating in database.\n"; try { $db = new PDO('sqlite:/home/in8wswn/data/shop_bot.sqlite3'); $up = $db->prepare("UPDATE users SET is_active = 0 WHERE user_id = ?"); $up->execute([$userId]); } catch (\Throwable $e2) {} } }