您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在 115 全站自动完成邀请助力任务,支持许愿树、抽奖等页面
当前为
// ==UserScript== // @name 115 助力助手 - 全站通用版(支持幸运5分钟抽奖) // @namespace http://tampermonkey.net/ // @version 1.5 // @description 在 115 全站自动完成邀请助力任务,支持许愿树、抽奖等页面 // @author You // @match https://*.115.com/* // @grant none // @license MIT // ==/UserScript== (function () { 'use strict'; let isRunning = false; let controller = new AbortController(); let startTime; let completedRequests = 0; // 防止重复加载 if (document.getElementById('boost-panel')) return; // 检查是否在有效页面显示面板(避免在 iframe 或无操作区域显示) function shouldShowPanel() { const validPaths = [ '/home/', '/social/games/lucky5', '/act/' ]; const currentPath = window.location.pathname; return validPaths.some(path => currentPath.includes(path)) || window.location.host.includes('f.115.com'); } if (!shouldShowPanel()) return; // 创建侧边栏控制按钮 const createToggleButton = () => { const btn = document.createElement('button'); btn.id = 'boost-toggle-btn'; btn.textContent = '助力工具'; Object.assign(btn.style, { position: 'fixed', top: '200px', right: '0', width: '80px', height: '40px', backgroundColor: '#007bff', color: 'white', border: 'none', borderRadius: '4px 0 0 4px', cursor: 'pointer', zIndex: '9999', fontSize: '14px', boxShadow: '0 2px 6px rgba(0,0,0,0.2)', }); btn.addEventListener('click', togglePanel); return btn; }; // 创建主面板 const createPanel = () => { const panel = document.createElement('div'); panel.id = 'boost-panel'; Object.assign(panel.style, { position: 'fixed', top: '120px', right: '-320px', width: '300px', height: '600px', backgroundColor: 'white', border: '1px solid #ddd', borderRadius: '8px 0 0 8px', boxShadow: '0 4px 12px rgba(0,0,0,0.15)', zIndex: '9999', transition: 'right 0.3s ease', overflow: 'hidden', fontFamily: 'Arial, sans-serif', }); panel.innerHTML = ` <div style="padding: 16px; background: #007bff; color: white; font-weight: bold;"> 115 助力助手 </div> <div style="padding: 16px;"> <label style="display:block;margin-bottom:8px;font-size:14px;">邀请码列表(每行一个)</label> <textarea id="boost-codes" rows="6" style="width:100%;font-family:monospace;font-size:12px;padding:8px; border:1px solid #ccc;border-radius:4px;resize:none;" placeholder="ABC123 XYZ789"></textarea> <div id="action-buttons" style="margin-top:12px;display:flex;gap:8px;"> <button id="start-boost" style="flex:1;background:#28a745;color:white; border:none;padding:10px 0;border-radius:4px;font-size:14px; cursor:pointer;">开始助力</button> </div> <div id="stats" style="margin-top:12px;font-size:12px;"> <div>总数: <span id="total">0</span></div> <div style="color:green;">成功: <span id="success">0</span></div> <div style="color:orange;">重复: <span id="duplicate">0</span></div> <div style="color:#666;">速率: <span id="rate">0</span> req/s</div> </div> <div style="margin-top:16px;font-size:14px;font-weight:bold;">执行日志</div> <div id="log-area" style="height:200px;overflow-y:auto;border:1px solid #eee; padding:8px;background:#f9f9f9;font-size:12px;"> <div class="log-item" style="color:#666;">等待启动...</div> </div> <!-- 加载动画 --> <div id="loading" style="display:none;text-align:center;margin-top:8px;"> <div style="display:inline-block;width:16px;height:16px;border:2px solid #ddd;border-top-color:#007bff;border-radius:50%;animation:spin 1s linear infinite;"></div> <span style="margin-left:8px;font-size:12px;color:#666;">处理中...</span> </div> </div> <style> @keyframes spin { to { transform: rotate(360deg); } } </style> `; return panel; }; // 添加日志(带自动滚动到底部) function addLog(message, color = 'black') { const logArea = document.getElementById('log-area'); const item = document.createElement('div'); item.className = 'log-item'; item.style.color = color; item.style.margin = '4px 0'; item.style.whiteSpace = 'nowrap'; item.style.overflow = 'hidden'; item.style.textOverflow = 'ellipsis'; const time = new Date().toLocaleTimeString(); item.textContent = `[${time}] ${message}`; logArea.appendChild(item); // 自动滚动到底部 requestAnimationFrame(() => { logArea.scrollTop = logArea.scrollHeight; }); } // 更新统计 function updateStats(key) { const el = document.getElementById(key); const val = parseInt(el.textContent || '0'); el.textContent = val + 1; } // 重置统计 function resetStats() { document.getElementById('success').textContent = '0'; document.getElementById('duplicate').textContent = '0'; document.getElementById('rate').textContent = '0'; } // 更新速率 function updateRate() { if (!startTime) return; const elapsed = (Date.now() - startTime) / 1000; const rate = elapsed > 0 ? (completedRequests / elapsed).toFixed(1) : '0'; document.getElementById('rate').textContent = rate; } // 发送助力请求(带重试机制) async function sendBoost(code, retryCount = 3) { for (let i = 0; i < retryCount; i++) { try { const formData = new FormData(); formData.append('boost_code', code); formData.append('source', 'link'); const response = await fetch('https://act.115.com/api/1.0/web/1.0/invite_boost/accept_invite', { method: 'POST', body: formData, credentials: 'include', signal: controller.signal }); if (!response.ok) throw new Error(`HTTP ${response.status}`); const data = await response.json(); return data; } catch (err) { if (err.name === 'AbortError') return { state: 0, message: '请求被取消' }; if (i === retryCount - 1) { return { state: 0, message: `网络错误(已重试${retryCount}次)` }; } // 指数退避 await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, i))); } } } // 主要逻辑 async function startBoost() { if (isRunning) return; const textarea = document.getElementById('boost-codes'); const codes = textarea.value .split('\n') .map(line => line.trim().toUpperCase()) .filter(line => /^[A-Z0-9]{6}$/.test(line)); if (codes.length === 0) { alert('请输入有效的6位邀请码(A-Z, 0-9),每行一个'); return; } isRunning = true; controller = new AbortController(); startTime = Date.now(); completedRequests = 0; // 冻结输入框和原按钮 textarea.disabled = true; const startBtn = document.getElementById('start-boost'); if (startBtn) startBtn.style.display = 'none'; // 显示加载动画 document.getElementById('loading').style.display = 'block'; // 清除旧的按钮 const actionButtons = document.getElementById('action-buttons'); const existingStop = document.getElementById('stop-boost'); if (existingStop) existingStop.remove(); // 添加“停止”按钮 const stopBtn = document.createElement('button'); stopBtn.id = 'stop-boost'; stopBtn.textContent = '停止助力'; stopBtn.style = 'flex:1;background:#dc3545;color:white;border:none;padding:10px 0;border-radius:4px;font-size:14px;cursor:pointer;'; stopBtn.onclick = () => { isRunning = false; controller.abort(); addLog('🛑 用户手动停止助力', 'red'); finishProcess(); }; actionButtons.appendChild(stopBtn); // 重置并显示总数 resetStats(); document.getElementById('total').textContent = codes.length; // 清空日志 document.getElementById('log-area').innerHTML = ''; addLog(`共发现 ${codes.length} 个有效邀请码,开始处理...`, 'blue'); // 逐个处理 for (const code of codes) { if (!isRunning) break; addLog(`正在助力: ${code}`, '#007bff'); const result = await sendBoost(code); if (result.state === 1) { addLog(`✅ 成功助力: ${result.data.inviter_name || '未知用户'}`, 'green'); updateStats('success'); } else if (result.code === 40203004 || result.message.includes('已经')) { addLog(`🟡 已助力过: ${code}`, 'orange'); updateStats('duplicate'); } else { addLog(`❌ 助力失败: ${result.message || '未知错误'}`, 'red'); } completedRequests++; updateRate(); // 更新速率 await new Promise(resolve => { if (!isRunning) return resolve(); setTimeout(resolve, 800); }); } finishProcess(); } function finishProcess() { isRunning = false; const stopBtn = document.getElementById('stop-boost'); if (stopBtn) stopBtn.remove(); // 隐藏加载动画 document.getElementById('loading').style.display = 'none'; const actionButtons = document.getElementById('action-buttons'); actionButtons.innerHTML = ''; const clearBtn = document.createElement('button'); clearBtn.textContent = '清空'; clearBtn.style = 'flex:1;background:#6c757d;color:white;border:none;padding:10px 0;border-radius:4px;font-size:14px;cursor:pointer;'; clearBtn.onclick = clearAll; const saveBtn = document.createElement('button'); saveBtn.textContent = '保存日志'; saveBtn.style = 'flex:1;background:#17a2b8;color:white;border:none;padding:10px 0;border-radius:4px;font-size:14px;cursor:pointer;'; saveBtn.onclick = saveLog; actionButtons.appendChild(clearBtn); actionButtons.appendChild(saveBtn); } function clearAll() { const textarea = document.getElementById('boost-codes'); textarea.value = ''; textarea.disabled = false; const logArea = document.getElementById('log-area'); logArea.innerHTML = '<div class="log-item" style="color:#666;">等待启动...</div>'; document.getElementById('total').textContent = '0'; resetStats(); const actionButtons = document.getElementById('action-buttons'); actionButtons.innerHTML = ` <button id="start-boost" style="flex:1;background:#28a745;color:white; border:none;padding:10px 0;border-radius:4px;font-size:14px; cursor:pointer;">开始助力</button> `; document.getElementById('start-boost').addEventListener('click', startBoost, { once: false }); } function saveLog() { const logArea = document.getElementById('log-area'); const logs = Array.from(logArea.children) .map(el => el.textContent) .join('\n'); const now = new Date(); const filename = `115助力助手-${now.getFullYear()}${String(now.getMonth()+1).padStart(2,'0')}${String(now.getDate()).padStart(2,'0')}${String(now.getHours()).padStart(2,'0')}${String(now.getMinutes()).padStart(2,'0')}${String(now.getSeconds()).padStart(2,'0')}.txt`; const blob = new Blob([logs], { type: 'text/plain;charset=utf-8' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; a.click(); URL.revokeObjectURL(url); } function togglePanel() { const panel = document.getElementById('boost-panel'); if (!panel) return; const currentRight = getComputedStyle(panel).right; panel.style.right = currentRight === '0px' ? '-320px' : '0'; } // 初始化函数 function init() { if (document.getElementById('boost-panel')) return; const toggleBtn = createToggleButton(); const panel = createPanel(); document.body.appendChild(toggleBtn); document.body.appendChild(panel); document.getElementById('start-boost').addEventListener('click', startBoost, { once: false }); } // 页面加载完成后初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址