// ==UserScript== // @name AirForce API 自动注册大管家 (v2.2 拟人+后台保活版) // @namespace http://tampermonkey.net/ // @version 2.2.0 // @description AirForce API 自动注册、获取 Key、拟人化 AI 模拟、Web Worker + Audio 后台持续保活 // @author Antigravity // @match https://api.airforce/signup/* // @match https://api.airforce/dashboard/* // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // @grant GM_xmlhttpRequest // @grant GM_openInTab // @connect api.airforce // @connect * // @noframes // ==/UserScript== (function () { 'use strict'; const BASE_CONFIG = { usernamePrefix: 'lizai', password: 'rrrrr112', signUpUrl: 'https://api.airforce/signup/', dashboardUrl: 'https://api.airforce/dashboard/', meApiUrl: 'https://api.airforce/api/me', autoCaptcha: true, useAI: true, }; // --- 序列号格式化逻辑 --- function formatCounter(num) { if (num <= 10000) return num.toString(); const offsetNum = num - 10001; const prefixIdx = Math.floor(offsetNum / 10000); const suffix = (offsetNum % 10000) + 1; const char = String.fromCharCode(97 + prefixIdx); return char + suffix; } // --- 共享数据获取与日志 --- const sharedData = { log: (msg, status = '') => { const time = new Date().toLocaleTimeString('zh-CN', { hour12: false }); let formattedMsg = `[${time}] ${msg}`; if (status) { const color = status === '200' ? '#2ed573' : (status === 'REQ' ? '#6c47ff' : '#ff4757'); formattedMsg = `[${time}] ${status} ${msg}`; } const logs = GM_getValue('af_remote_logs', []); logs.push(formattedMsg); GM_setValue('af_remote_logs', logs.slice(-50)); if (status !== 'SILENT') console.log(`[AirForce] ${msg}`); }, getRemoteLogs: () => GM_getValue('af_remote_logs', []), }; const storage = { getCounter: () => parseInt(GM_getValue('af_counter', 1)), setCounter: (val) => { GM_setValue('af_counter', val); const view = document.getElementById('af-counter-view'); if (view) view.innerText = formatCounter(val); }, getAutoLoop: () => GM_getValue('af_auto_loop', true), setAutoLoop: (val) => GM_setValue('af_auto_loop', val), getRecords: () => { const raw = GM_getValue('af_records', '[]'); try { return JSON.parse(raw); } catch { return []; } }, saveRecord: (record) => { const records = storage.getRecords(); // 去重检查:如果 API Key 已存在,则不再重复保存 if (records.some(r => r.api_key === record.api_key)) { sharedData.log(`Key 已存在,跳过保存: ${record.api_key.substring(0, 16)}...`, 'SILENT'); return; } records.push({ ...record, time: new Date().toLocaleString('zh-CN', { hour12: false }) }); GM_setValue('af_records', JSON.stringify(records)); sharedData.log(`Key 已保存: ${record.api_key.substring(0, 16)}...`, '200'); } }; // --- 后端后台运行优化 (Web Worker 心跳) --- const bgTimer = { worker: null, callbacks: [], init: function () { if (this.worker) return; try { const blob = new Blob([` let intervalId = null; self.onmessage = function(e) { if (e.data === 'start') { if (intervalId) clearInterval(intervalId); intervalId = setInterval(() => self.postMessage('tick'), 1000); } else if (e.data === 'stop') { if (intervalId) clearInterval(intervalId); intervalId = null; } }; `], { type: 'application/javascript' }); this.worker = new Worker(URL.createObjectURL(blob)); this.worker.onmessage = () => { this.callbacks.forEach(cb => cb()); }; sharedData.log('后台心跳定时器已就绪 (Web Worker)', 'SILENT'); } catch (e) { console.error('[AirForce] Worker 初始化失败', e); } }, start: function (cb) { this.init(); if (cb && !this.callbacks.includes(cb)) this.callbacks.push(cb); if (this.worker) { this.worker.postMessage('start'); sharedData.log('后台心跳定时器已启动 (Web Worker)', 'SILENT'); } }, stop: function () { if (this.worker) this.worker.postMessage('stop'); this.callbacks = []; } }; // --- 音频保活系统 (防止标签页挂起) --- const keepAlive = { audio: null, init: function () { if (this.audio) return; this.audio = document.createElement('audio'); this.audio.loop = true; this.audio.muted = false; // 不静音才能触发标签页蓝标/活动 this.audio.volume = 0.01; this.audio.title = "AirForce Auto-Register Keep-alive"; // 使用 jsdelivr 托管的静音音频 this.audio.src = 'https://cdn.jsdelivr.net/gh/anars/blank-audio/10-seconds-of-silence.mp3'; // 冗余设计的无限循环守卫 this.audio.onended = () => { if (storage.getAutoLoop()) { this.audio.currentTime = 0; this.audio.play().catch(() => { }); } }; document.body.appendChild(this.audio); }, play: function () { this.init(); const attemptPlay = () => { this.audio.play().then(() => { sharedData.log('保活音频流已成功启动 (7x24h 保护)', 'SILENT'); }).catch(() => { // 每秒重试,直到用户点击页面或策略允许 if (storage.getAutoLoop()) setTimeout(attemptPlay, 1000); }); }; attemptPlay(); }, stop: function () { if (this.audio) this.audio.pause(); } }; // --- 辅助函数 --- function waitForElement(selector, timeout = 15000) { return new Promise((resolve, reject) => { const start = Date.now(); const interval = setInterval(() => { const el = document.querySelector(selector); if (el) { clearInterval(interval); resolve(el); } else if (Date.now() - start > timeout) { clearInterval(interval); reject(new Error(`超时: ${selector}`)); } }, 500); }); } async function setValue(input, value) { if (!input) return; const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set; setter.call(input, value); input.dispatchEvent(new Event('input', { bubbles: true })); input.dispatchEvent(new Event('change', { bubbles: true })); input.blur(); await new Promise(r => setTimeout(r, 100)); } // --- AI 拟人化引擎 --- const AISimulator = { binomial: (n, k) => { let coeff = 1; for (let i = n - k + 1; i <= n; i++) coeff *= i; for (let i = 1; i <= k; i++) coeff /= i; return coeff; }, bernstein: (t, i, n) => AISimulator.binomial(n, i) * Math.pow(t, i) * Math.pow(1 - t, n - i), getBezierPoint: (t, points) => { let n = points.length - 1; let x = 0, y = 0; for (let i = 0; i <= n; i++) { let b = AISimulator.bernstein(t, i, n); x += points[i][0] * b; y += points[i][1] * b; } return [x, y]; }, easing: (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t, generatePath: (start, end) => { const dist = Math.sqrt(Math.pow(end[0] - start[0], 2) + Math.pow(end[1] - start[1], 2)); const knotsCount = 2 + Math.floor(dist / 200); const knots = [start]; for (let i = 1; i <= knotsCount; i++) { const t = i / (knotsCount + 1); const knotX = start[0] + (end[0] - start[0]) * t + (Math.random() - 0.5) * (dist * 0.2); const knotY = start[1] + (end[1] - start[1]) * t + (Math.random() - 0.5) * (dist * 0.2); knots.push([knotX, knotY]); } knots.push(end); const path = []; const steps = Math.max(30, Math.floor(dist / 10) + Math.floor(Math.random() * 20)); for (let i = 0; i < steps; i++) { const t = i / (steps - 1); const easedT = AISimulator.easing(t); const point = AISimulator.getBezierPoint(easedT, knots); point[0] += (Math.random() - 0.5) * 0.5; point[1] += (Math.random() - 0.5) * 0.5; path.push({ x: point[0], y: point[1] }); } return path; } }; async function simulateHumanoidClick(targetEl) { const rect = targetEl.getBoundingClientRect(); if (rect.width === 0 || rect.height === 0) return false; const targetX = rect.left + rect.width / 2 + (Math.random() - 0.5) * (rect.width * 0.5); const targetY = rect.top + rect.height / 2 + (Math.random() - 0.5) * (rect.height * 0.5); const startX = Math.random() > 0.5 ? -100 : window.innerWidth + 100; const startY = Math.random() * window.innerHeight; const path = AISimulator.generatePath([startX, startY], [targetX, targetY]); let ghost = document.createElement('div'); ghost.style.cssText = `position:fixed; width:8px; height:8px; background:rgba(108, 71, 255, 0.7); border-radius:50%; z-index:100000; pointer-events:none;`; document.body.appendChild(ghost); for (const point of path) { ghost.style.left = point.x + 'px'; ghost.style.top = point.y + 'px'; await new Promise(r => setTimeout(r, 5 + Math.random() * 5)); } await new Promise(r => setTimeout(r, 100 + Math.random() * 100)); const clickParams = { bubbles: true, cancelable: true, clientX: targetX, clientY: targetY, view: window }; targetEl.dispatchEvent(new MouseEvent('mousedown', clickParams)); await new Promise(r => setTimeout(r, 50 + Math.random() * 50)); targetEl.dispatchEvent(new MouseEvent('mouseup', clickParams)); targetEl.dispatchEvent(new MouseEvent('click', clickParams)); ghost.remove(); return true; } function findIframeRecursively(root) { try { if (!root) return null; const iframes = Array.from(root.querySelectorAll('iframe')); const target = iframes.find(f => f.src && f.src.includes('challenges.cloudflare.com')); if (target) return target; const children = Array.from(root.querySelectorAll('*')); for (const child of children) { try { if (child.shadowRoot) { const found = findIframeRecursively(child.shadowRoot); if (found) return found; } } catch (e) { } } } catch (e) { } return null; } // --- 核心业务 --- let isWorking = false; async function performRegistration() { if (isWorking || !storage.getAutoLoop()) return; isWorking = true; try { sharedData.log('准备开始注册流程...', 'REQ'); const counter = storage.getCounter(); const formattedCounter = formatCounter(counter); const timestamp = Date.now().toString().slice(-6); const username = `${BASE_CONFIG.usernamePrefix}_${formattedCounter}_${timestamp}`; sharedData.log(`生成用户名: ${username}`, 'REQ'); const uInput = document.getElementById('username') || document.querySelector('input[placeholder*="用户名"i]'); const pInput = document.getElementById('password') || document.querySelector('input[placeholder*="密码"i]'); const cpInput = document.getElementById('confirmPassword') || document.querySelector('input[placeholder*="确认"i]'); if (!uInput || !pInput) { sharedData.log('未找到输入框,重试中...', 'ERR'); setTimeout(() => location.reload(), 3000); return; } await setValue(uInput, username); await setValue(pInput, BASE_CONFIG.password); if (cpInput) await setValue(cpInput, BASE_CONFIG.password); let attempts = 0; const checkAndSubmit = async () => { if (!storage.getAutoLoop()) return; const submitBtn = document.querySelector('button[type="submit"]') || Array.from(document.querySelectorAll('button')).find(b => b.innerText.includes('账户') || b.innerText.includes('Create')); if (!submitBtn) return; const isDisabled = submitBtn.disabled || submitBtn.getAttribute('aria-disabled') === 'true' || submitBtn.classList.contains('opacity-50'); if (!isDisabled) { sharedData.log('检测到按钮已激活,点击提交', 'REQ'); submitBtn.click(); storage.setCounter(counter + 1); setTimeout(checkLoginStatus, 8000); // 增加等待时长,给后端反馈留时间 } else { attempts++; // 检查是否出现了错误提示 if (document.body.innerText.includes('Username already exists')) { checkLoginStatus(); return; } if (attempts < 300) { if (attempts === 5) { const cfIframe = findIframeRecursively(document); if (cfIframe) simulateHumanoidClick(cfIframe.parentElement || cfIframe); } setTimeout(checkAndSubmit, 1000); } else { location.reload(); } } }; checkAndSubmit(); } catch (e) { isWorking = false; sharedData.log('注册异常: ' + e.message, 'ERR'); } } async function checkLoginStatus() { if (location.pathname.includes('dashboard')) { sharedData.log('进入控制台,获取 API Key...', '200'); await fetchApiKey(); } else if (document.body.innerText.includes('Welcome') || document.body.innerText.includes('Success')) { location.href = BASE_CONFIG.dashboardUrl; } else if (document.body.innerText.includes('Username already exists')) { sharedData.log('用户名已存在!自动跳过并刷新重启...', 'ERR'); isWorking = false; // 再次确保计数器增加 (click 后面已经加过一次,但为了保险这里再检查) setTimeout(() => location.reload(), 2000); } else { // 兜底机制:如果 10 秒后还在注册页且没有任何状态变化,重置状态允许重试 setTimeout(() => { if (location.pathname.includes('signup') && isWorking) { sharedData.log('操作超时或状态不明,重置流程...', 'SILENT'); isWorking = false; } }, 10000); } } async function fetchApiKey() { try { sharedData.log('获取 Key 中...', 'REQ'); let token = localStorage.getItem('token') || localStorage.getItem('access_token'); if (!token) { const match = document.cookie.match(/token=([^;]+)/); if (match) token = match[1]; } if (!token) return; GM_xmlhttpRequest({ method: 'GET', url: BASE_CONFIG.meApiUrl, headers: { 'Authorization': `Bearer ${token}`, 'Accept': 'application/json' }, onload: function (response) { if (response.status === 200) { try { const data = JSON.parse(response.responseText); if (data.api_key) { storage.saveRecord({ username: data.username, api_key: data.api_key }); if (storage.getAutoLoop()) setTimeout(logoutAndNext, 3000); } } catch (e) { } } } }); } catch (e) { } } function logoutAndNext() { localStorage.clear(); sessionStorage.clear(); document.cookie.split(";").forEach(function (c) { document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/"); }); location.href = BASE_CONFIG.signUpUrl; } // --- 页面路由检测 --- function detectPageAndRun() { if (!storage.getAutoLoop()) return; const host = window.location.hostname; if (location.href.includes('signup')) { performRegistration(); } else if (location.href.includes('dashboard')) { checkLoginStatus(); } else if (host === 'api.airforce' && location.pathname === '/') { location.href = BASE_CONFIG.signUpUrl; } } // --- UI 注入 --- function injectUI() { if (document.getElementById('af-ui')) return; const ui = document.createElement('div'); ui.id = 'af-ui'; ui.style.cssText = `position:fixed; top:20px; right:20px; z-index:99999; background:#1e1e2e; color:#cdd6f4; padding:15px; border-radius:10px; width:260px; font-family:sans-serif; box-shadow:0 4px 15px rgba(0,0,0,0.5); border:1px solid #45475a;`; const currentCounter = storage.getCounter(); ui.innerHTML = `
AirForce Pro v2.2 OFF
序号设置: (显示: ${formatCounter(currentCounter)})
已采 Key: ${storage.getRecords().length}
后台保活系统 (7x24h 保护) ● OFF
音频保活: × OFF 后台心跳: × OFF
等待启动...
`; document.body.appendChild(ui); document.getElementById('af-toggle').onclick = function () { const isLooping = !storage.getAutoLoop(); storage.setAutoLoop(isLooping); if (isLooping) { keepAlive.play(); bgTimer.start(() => detectPageAndRun()); } else { keepAlive.stop(); bgTimer.stop(); } updateUI(); }; document.getElementById('af-counter-input').onchange = (e) => { storage.setCounter(parseInt(e.target.value) || 1); }; document.getElementById('af-view').onclick = function () { const records = storage.getRecords(); // 导出时进行二次去重,确保纯净 const uniqueKeys = [...new Set(records.map(r => r.api_key).filter(k => k))]; const txt = uniqueKeys.join('\n'); if (!txt) return; const b = new Blob([txt], { type: 'text/plain' }); const u = URL.createObjectURL(b); const a = document.createElement('a'); a.href = u; a.download = `pure_keys_${Date.now()}.txt`; a.click(); URL.revokeObjectURL(u); }; document.getElementById('af-clear').onclick = function () { if (confirm('确定要清空所有已保存的 API Key 吗?此操作不可撤销!')) { GM_setValue('af_records', '[]'); sharedData.log('所有 API Key 已清空', 'SILENT'); updateUI(); } }; setInterval(updateUI, 1000); } function updateUI() { const isLooping = storage.getAutoLoop(); const statusView = document.getElementById('af-status'); const kaStatus = document.getElementById('af-ka-status'); const btn = document.getElementById('af-toggle'); const logsView = document.getElementById('af-logs'); const counterView = document.getElementById('af-counter-view'); if (statusView) { statusView.innerText = isLooping ? 'RUNNING' : 'OFF'; statusView.style.background = isLooping ? '#a6e3a1' : '#f38ba8'; } if (kaStatus) { const isAudioActive = keepAlive.audio && !keepAlive.audio.paused; const isWorkerActive = bgTimer.worker && (isLooping || bgTimer.callbacks.length > 0); const kaAudio = document.getElementById('af-ka-audio'); const kaWorker = document.getElementById('af-ka-worker'); if (kaAudio) { if (isAudioActive) { kaAudio.innerText = '✓ ACTIVATED'; kaAudio.style.color = '#a6e3a1'; } else if (keepAlive.audio) { kaAudio.innerText = '⚠ WAITING'; kaAudio.style.color = '#fab387'; } else { kaAudio.innerText = '× OFF'; kaAudio.style.color = '#ff4757'; } } if (kaWorker) { kaWorker.innerText = isWorkerActive ? '✓ ACTIVATED' : '× OFF'; kaWorker.style.color = isWorkerActive ? '#a6e3a1' : '#ff4757'; } if (isAudioActive && isWorkerActive) { kaStatus.innerText = '● 坚不可摧'; kaStatus.style.color = '#a6e3a1'; } else if (isLooping) { kaStatus.innerText = '● 激活中...'; kaStatus.style.color = '#fab387'; } else { kaStatus.innerText = '● OFF'; kaStatus.style.color = '#ff4757'; } } if (btn) btn.innerText = isLooping ? '停止' : '开始自动注册'; if (logsView) { logsView.innerHTML = sharedData.getRemoteLogs().join('
'); logsView.scrollTop = logsView.scrollHeight; } if (counterView) counterView.innerText = formatCounter(storage.getCounter()); } // --- 入口与唤醒 --- function start() { if (window.self !== window.top) return; // 二次确认不在 iframe 运行 injectUI(); updateUI(); // 立即执行一次 UI 更新,避免显示默认的 OFF // 自动清理存量重复数据 const records = storage.getRecords(); const seen = new Set(); const cleanRecords = records.filter(r => { if (!r.api_key || seen.has(r.api_key)) return false; seen.add(r.api_key); return true; }); if (cleanRecords.length !== records.length) { GM_setValue('af_records', JSON.stringify(cleanRecords)); sharedData.log(`已自动清理 ${records.length - cleanRecords.length} 条存量重复 Key`, 'SILENT'); } const wakeup = () => { if (storage.getAutoLoop()) { keepAlive.play(); bgTimer.start(() => detectPageAndRun()); sharedData.log('已通过交互激活后台保活', 'SILENT'); } window.removeEventListener('mousedown', wakeup); window.removeEventListener('keydown', wakeup); window.removeEventListener('touchstart', wakeup); }; window.addEventListener('mousedown', wakeup); window.addEventListener('keydown', wakeup); window.addEventListener('touchstart', wakeup); if (storage.getAutoLoop()) { bgTimer.start(() => detectPageAndRun()); keepAlive.play(); sharedData.log('后台保活已自动开启', 'SILENT'); } } if (document.readyState === 'complete') start(); else window.addEventListener('load', start); })();